Python usage notes - iterable stuff: Difference between revisions
mNo edit summary |
m (→Sorting) |
||
Line 1: | Line 1: | ||
{{Pythonstuff}} | {{Pythonstuff}} | ||
==Iterators== | |||
<!-- | |||
The [https://docs.python.org/3/c-api/iter.html (py3) iterator protocol] | |||
In general, an iterator needs to | |||
__iter__() | |||
__next__() | |||
StopIteration | |||
Every generator is specific type of iterator, but not every iterator is a generator? | |||
Generally, if a generator does what you want, it is easier to write than an iterator | |||
Python3 also chose to return more things as iterable/genrator things, rather than materialized lists. | |||
For example: | |||
* map() and filter() returns an iterator, not a list | |||
:: in py2, they returned a list, and you would need itertools.imap() and itertools.ifilter() for the iterator behaviour) | |||
python3 also renamed g.next() to g.__next__() for consistency | |||
: note that if you use the built-in function next() then you only care about this when ''writing'' iterators, not ''using'' them | |||
: there's more to it - read [https://peps.python.org/pep-3114/ PEP 3114] for details | |||
--> | |||
==Sorting== | ==Sorting== |
Revision as of 14:53, 23 January 2024
Syntaxish: syntax and language · changes and py2/3 · decorators · importing, modules, packages · iterable stuff · concurrency
IO: networking and web · filesystem Data: Numpy, scipy · pandas, dask · struct, buffer, array, bytes, memoryview · Python database notes Image, Visualization: PIL · Matplotlib, pylab · seaborn · bokeh · plotly
Stringy: strings, unicode, encodings · regexp · command line argument parsing · XML speed, memory, debugging, profiling · Python extensions · semi-sorted |
Iterators
Sorting
sorted() for a sorted copy
object.sort() for in-place
This is stable sorting, so you can do secondary sorting in multiple passes.
You can also do it in one pass, using key
key argument (py2, py3)
The key parameter should be a callable that fetches the value to sort on from an object.
This allows:
- normalization, e.g. case-insensitive sort via:
sorted(['foo','BAR'], key=lambda x: x.lower()) == ['BAR', 'foo']
- sorting by specific columns
sorted( [('b',2,),('a',1)], key=lambda l: l[1] ) == [('a', 1), ('b', 2)]
- sorting by multiple columns (or other aspects), when you make the key function return a tuple, for example:
- e.g. empty strings last, via:
sorted( ['b','','A'], key=lambda x: (x=='', x.lower())) == ['A', 'b', '']
cmp argument (removed in py3)
You can write an arbitrary comparison function, like
sorted( [[1,2], [2,1]], lambda a,b: cmp(b[1], a[1])) # second column descending
Almost all cmp functions I've seen can be easily rewritten with key (and reverse), possibly decorate-sort-undecorate. In this case:
sorted( [[1,2], [2,1]], key=lambda x: x[1], reverse=True)
As key tends to be faster, cmp is sort of redundant, and python3 removed cmp.
If you've got some cmp functions that are awkward to rewrite, you can use functools.cmp_to_key as a stopgap
See also: