3 from itertools
import chain
, izip
, count
19 def filter_null(iterable
):
20 return [ x
for x
in iterable
if x
]
22 def filter_both(predicate
, iterable
):
31 def flatten(list_of_lists
):
32 return chain
.from_iterable(list_of_lists
)
34 def flatten_twice(list_of_lists_of_lists
):
35 return flatten(flatten( list_of_lists_of_lists
))
38 """Given an iterable of pairs (key, value), return the key corresponding to the greatest value."""
39 return max(pairs
, key
=lambda x
:x
[1])[0]
42 return min(pairs
, key
=lambda x
:x
[1])[0]
44 def argmax_index(values
):
45 """Given an iterable of values, return the index of the greatest value."""
46 return argmax(izip(count(), values
))
48 def argmin_index(values
):
49 return argmin(izip(count(), values
))
51 def bucket_by_key(iterable
, key_fc
):
53 Throws items in @iterable into buckets given by @key_fc function.
55 >>> bucket_by_key([1,2,-3,4,5,6,-7,8,-9], lambda num: 'neg' if num < 0 else 'nonneg')
56 {'neg': [-3, -7, -9], 'nonneg': [1, 2, 4, 5, 6, 8]}
60 buckets
.setdefault(key_fc(item
), []).append(item
)
63 def first_true_pred(predicates
, value
):
64 """Given a list of predicates and a value, return the index of first predicate,
65 s.t. predicate(value) == True. If no such predicate found, raises IndexError."""
66 for num
, pred
in enumerate(predicates
):
77 An alternative implementation of functools partial, allowing to specify args
78 from the right as well.
80 def __init__(self
, func
, args
=(), keywords
={}, right
=False):
83 self
.keywords
= keywords
87 return repr(self
.func
)
90 return "MyPartial(%s, %s, %s%s)"%(self
._frepr
(),
91 repr(self
.args
), repr(self
.keywords
),
92 ", right=True" if self
.right
else '')
94 def _merge_args(self
, args_new
):
96 return args_new
+ tuple(self
.args
)
97 return tuple(self
.args
) + args_new
99 def _merge_kwargs(self
, kwargs_new
):
100 kwargs
= self
.keywords
.copy()
101 kwargs
.update(kwargs_new
)
104 def __call__(self
, *args_new
, **kwargs_new
):
105 args
= self
._merge
_args
(args_new
)
106 kwargs
= self
._merge
_kwargs
(kwargs_new
)
107 return self
.func(*args
, **kwargs
)
109 def partial(f
, *args
, **kwargs
):
114 partial(minus, 10) is like:
116 lambda b : minus(10, b)
118 return MyPartial(f
, args
, kwargs
)
120 def partial_right(f
, *args
, **kwargs
):
125 partial_right(minus, 10) is like:
127 lambda a : minus(a, 10)
129 return MyPartial(f
, args
, kwargs
, right
=True)
132 # Type info and conversion
143 return is_conv(x
, int)
146 return is_conv(x
, float)
148 def is_type(x
, type):
155 return is_type(x
, int)
157 def is_type_float(x
):
158 return is_type(x
, float)
161 # Hash utils & random strings
165 return hashlib
.sha256(txt
).hexdigest()
167 return hashlib
.sha512(txt
).hexdigest()
169 def random_hash(LEN
=10):
170 return str(random
.randint(10**(LEN
-1),10**LEN
-1))
172 def unique_hash(length
=32):
173 """Returns "unique" hash. (the shorter the length, the less unique it is).
174 I consider one in 16**32 to be pretty unique. :-) (supposing that sha256 works).
177 return sha256( "%.20f %s %d %d"%(time
.time(), random_hash(), os
.getpid(), threading
.current_thread().ident
) ) [:length
]
179 time_based_random_hash
= unique_hash
181 def tmp_names(base
=random_hash(), first_simple
=False):
187 yield "%s_%d"%(base
, i
)
195 return unicode(st
).encode('utf-8')
197 def remove_accents(istr
):
198 nkfd_form
= unicodedata
.normalize('NFKD', unicode(istr
))
199 return u
"".join([c
for c
in nkfd_form
if not unicodedata
.combining(c
)])
201 def unicode2ascii(unistr
):
202 return remove_accents(unistr
).encode('ascii', 'ignore')
204 def pad2len(s
, l
, padchar
):
206 return s
+ padchar
* (l
- len(s
))
213 def iter_files(directory
):
214 for (dirpath
, _
, filenames
) in os
.walk(directory
):
215 for name
in filenames
:
216 yield os
.path
.join(dirpath
, name
)
218 def timeit(f
, *args
, **kwargs
):
220 ret
= f(*args
, **kwargs
)
221 diff
= time
.time() - t0
222 print "TOOK: %.3f sec"%(diff
,)
225 if __name__
== '__main__':
227 def fc ( a
, b
, c
='def C', d
='def D' ):
228 return "a=%d, b=%d, c=%s, d=%s"%(a
,b
,c
,d
)
230 nor
= partial(fc
, 20, c
=10)
231 zpr
= partial_right(fc
, 20, c
=10)
233 print "puvodni:", repr(fc
)
234 print "normalni:", repr(nor
)
235 print "zprava:", repr(zpr
)
237 print "normalni(10) = ", nor(10)
238 print "zprava(10) = ", zpr(10)
240 nor2
= partial(nor
, 10)
241 print "double:", nor2
242 print "double()", nor2()
245 def __call__(self
, a
, b
):
246 return "a=%s b=%s"%(a
,b
)
248 ca
= partial(Fobj(), 10)