これを行うために使用できますcollections.Counter
:
>>> from collections import Counter
>>> a = ( ('309','308','308'), ('309','308','307'), ('308', '309','306', '304'))
>>> Counter((x, y) for (x, y, *z) in a)
Counter({('309', '308'): 2, ('308', '309'): 1})
>>> Counter((x, z) for (x, y, z, *w) in a)
Counter({('308', '306'): 1, ('309', '308'): 1, ('309', '307'): 1})
ここでは、Python 3.xより前には存在しなかった拡張タプルアンパックも使用しています。これは、長さが不確かなタプルがある場合にのみ必要です。python 2.xでは、代わりに次のことを行うことができます。
Counter((item[0], item[1]) for item in a)
しかし、これがどれほど効率的かは言えませんでした。悪いことではないと思います。
ACounter
には-のdict
ような構文があります。
>>> count = Counter((x, y) for (x, y, *z) in a)
>>> count['309', '308']
2
編集:長さが1より大きい可能性があるとおっしゃいましたが、この場合、必要な長さより短いと開梱できないため、問題が発生する可能性があります。解決策は、ジェネレータ式を変更して、必要な形式でないものを無視することです。
Counter((item[0], item[1]) for item in a if len(item) >= 2)
例えば:
>>> a = ( ('309',), ('309','308','308'), ('309','308','307'), ('308', '309','306', '304'))
>>> Counter((x, y) for (x, y, *z) in a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.2/collections.py", line 460, in __init__
self.update(iterable, **kwds)
File "/usr/lib/python3.2/collections.py", line 540, in update
_count_elements(self, iterable)
File "<stdin>", line 1, in <genexpr>
ValueError: need more than 1 value to unpack
>>> Counter((item[0], item[1]) for item in a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.2/collections.py", line 460, in __init__
self.update(iterable, **kwds)
File "/usr/lib/python3.2/collections.py", line 540, in update
_count_elements(self, iterable)
File "<stdin>", line 1, in <genexpr>
IndexError: tuple index out of range
>>> Counter((item[0], item[1]) for item in a if len(item) >= 2)
Counter({('309', '308'): 2, ('308', '309'): 1})
可変長カウントが必要な場合、最も簡単な方法はリストスライスを使用することです。
start = 0
end = 2
Counter(item[start:end] for item in a if len(item) >= start+end)
もちろん、これは連続実行でのみ機能します。列を個別に選択する場合は、もう少し作業を行う必要があります。
def pick(seq, indices):
return tuple([seq[i] for i in indices])
columns = [1, 3]
maximum = max(columns)
Counter(pick(item, columns) for item in a if len(item) > maximum)