Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ad9d96b

Browse files
committed
Issue #4615. Document how to use itertools for de-duping.
1 parent 80a50ac commit ad9d96b

2 files changed

Lines changed: 60 additions & 0 deletions

File tree

Doc/library/itertools.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,3 +606,27 @@ which incur interpreter overhead.
606606
return
607607
indices[i:] = [indices[i] + 1] * (r - i)
608608
yield tuple(pool[i] for i in indices)
609+
610+
def unique_everseen(iterable, key=None):
611+
"List unique elements, preserving order. Remember all elements ever seen."
612+
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
613+
# unique_everseen('ABBCcAD', str.lower) --> A B C D
614+
seen = set()
615+
seen_add = seen.add
616+
if key is None:
617+
for element in iterable:
618+
if element not in seen:
619+
seen_add(element)
620+
yield element
621+
else:
622+
for element in iterable:
623+
k = key(element)
624+
if k not in seen:
625+
seen_add(k)
626+
yield element
627+
628+
def unique_justseen(iterable, key=None):
629+
"List unique elements, preserving order. Remember only the element just seen."
630+
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
631+
# unique_justseen('ABBCcAD', str.lower) --> A B C A D
632+
return map(next, map(itemgetter(1), groupby(iterable, key)))

Lib/test/test_itertools.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,30 @@ def __init__(self, newarg=None, *args):
12981298
... indices[i:] = [indices[i] + 1] * (r - i)
12991299
... yield tuple(pool[i] for i in indices)
13001300
1301+
>>> def unique_everseen(iterable, key=None):
1302+
... "List unique elements, preserving order. Remember all elements ever seen."
1303+
... # unique_everseen('AAAABBBCCDAABBB') --> A B C D
1304+
... # unique_everseen('ABBCcAD', str.lower) --> A B C D
1305+
... seen = set()
1306+
... seen_add = seen.add
1307+
... if key is None:
1308+
... for element in iterable:
1309+
... if element not in seen:
1310+
... seen_add(element)
1311+
... yield element
1312+
... else:
1313+
... for element in iterable:
1314+
... k = key(element)
1315+
... if k not in seen:
1316+
... seen_add(k)
1317+
... yield element
1318+
1319+
>>> def unique_justseen(iterable, key=None):
1320+
... "List unique elements, preserving order. Remember only the element just seen."
1321+
... # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
1322+
... # unique_justseen('ABBCcAD', str.lower) --> A B C A D
1323+
... return map(next, map(itemgetter(1), groupby(iterable, key)))
1324+
13011325
This is not part of the examples but it tests to make sure the definitions
13021326
perform as purported.
13031327
@@ -1360,6 +1384,18 @@ def __init__(self, newarg=None, *args):
13601384
>>> list(combinations_with_replacement('abc', 2))
13611385
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]
13621386
1387+
>>> list(unique_everseen('AAAABBBCCDAABBB'))
1388+
['A', 'B', 'C', 'D']
1389+
1390+
>>> list(unique_everseen('ABBCcAD', str.lower))
1391+
['A', 'B', 'C', 'D']
1392+
1393+
>>> list(unique_justseen('AAAABBBCCDAABBB'))
1394+
['A', 'B', 'C', 'D', 'A', 'B']
1395+
1396+
>>> list(unique_justseen('ABBCcAD', str.lower))
1397+
['A', 'B', 'C', 'A', 'D']
1398+
13631399
"""
13641400

13651401
__test__ = {'libreftest' : libreftest}

0 commit comments

Comments
 (0)