Я не могу найти, где в моем последнем коде существует кортеж
Каждый элемент bus_stop_ID
является кортежем.
Напомним, у вас есть список переменныхдлины, и вы хотите найти самый распространенный элемент во всей этой структуре.
Звучит как идеальное применение для collections.Counter
:
>>> from collections import Counter
>>> bus_stop_ID = [('id1', 'id2', 'id3'), ('id1',), ('id1', 'id3', 'id5')]
>>> [(stop_id, count)] = sum(map(Counter, bus_stop_ID), Counter()).most_common(1)
>>> stop_id
'id1'
>>> count
3
Здесь:
map(Counter, bus_stop_ID)
подсчитывает идентификаторы автобусных остановок по каждому маршруту отдельно; sum(..., Counter())
объединяет подсчеты по маршрутам; .most_common(1)
возвращаетНаиболее распространенный идентификатор автобусной остановки в агрегированных счетах (как одноэлементный список, содержащий 2-кортеж, который состоит из идентификатора автобусной остановки и его счетчика).
Альтернативой является объединение всехмаршрутов (используя sum()
), а затем выполните подсчет:
>>> [(stop_id, count)] = Counter(sum(bus_stop_ID, ())).most_common(1)
Это короче, но менее эффективно, поскольку необходимо объединить все маршруты в один (потенциально гигантский) кортеж.
A - несколько причудливый - способ обойти эту неэффективность с помощью itertools.chain()
:
>>> Counter(itertools.chain(*bus_stop_ID)).most_common(1)
[('id1', 3)]
Это просто перебирает все идентификаторы автобусной остановки на первом маршруте, затем на втором и т. Д., Делая подсчет по пути.
Из любопытства,Я сравнил все три метода с произвольно выбранным списком из 10 000 кортежей, и результаты весьма интересны:
In [11]: %timeit sum(map(Counter, bus_stop_ID), Counter()).most_common(1)
1 loop, best of 3: 235 ms per loop
In [12]: %timeit Counter(sum(bus_stop_ID, ())).most_common(1)
1 loop, best of 3: 2.64 s per loop
In [13]: %timeit Counter(itertools.chain(*bus_stop_ID)).most_common(1)
10 loops, best of 3: 17.3 ms per loop