#python #python-3.x
#python #python-3.x
Вопрос:
У меня есть (очень длинный) список с такой структурой:
li1 = [[1.4, b][1.5, a][1.6, c][1,4, b][1.7,c][1.4, a][1.6,c]]
Я хочу написать цикл, который вычисляет количество элементов li1[i][0
]` с одинаковым значением и помещает эту информацию в новый список, вот так:
li2 = [[1.4, 3][1.5, 1][1.6, 2][1.7, 1]]
Проблема для меня в том, что я не знаю, какое значение или сколько разных значений я ищу..
Спасибо
Ответ №1:
from collections import Counter
a, b, c = 'abc'
li1 = [[1.4, b], [1.5, a], [1.6, c], [1.4, b], [1.7, c], [1.4, a], [1.6, c]]
sorted(Counter(x[0] for x in li1).items())
( map
list
воспользуйтесь этим, если вам отчаянно нужен список списков.)
Ответ №2:
>>> li1 = [[1.4, 'b'],[1.5, 'a'],[1.6, 'c'],[1.4, 'b'],[1.7,'c'],[1.4, 'a'],[1.6,'c']]
Сначала мы создаем словарь с ключами типа (1.4,'b')
и значениями, обозначающими количество этих ключевых элементов в исходном списке:
>>> d = {}
>>> for el in li1:
el = el[0]
d[el] = d.get(el,0) 1
Итак, словарь выглядит следующим образом:
>>> d
{1.5: 1, 1.4: 3, 1.7: 1, 1.6: 2}
Также обратите внимание, что используется d.get
. Поскольку изначально словарь не содержит элементов, поэтому get возвращает, 0
когда элемента нет (второй аргумент get
). Существуют другие методы для достижения такого поведения: вы можете использовать DefalutDict
или Counter
, как используется в другом ответе.
Затем мы используем словарь для создания необходимого списка:
>>>[[key,value] for key,value in d.items()]
[[1.5, 1], [1.4, 3], [1.7, 1], [1.6, 2]]
Ответ №3:
Поскольку вас интересует только первое значение списка, первым шагом является извлечение его из каждого из подсписков (которые, кстати, должны быть тупелями).
>>> a,b,c = 'abc'
>>> li1 = [[1.4, b], [1.5, a], [1.6, c], [1,4, b], [1.7, c], [1.4, a], [1.6, c]]
>>> firsts = map(lambda sublist: sublist[0], li1)
map
вызывает его первый аргумент с элементом второго аргумента. Поскольку первым аргументом здесь является анонимная функция (lambda), которая возвращает первый элемент своего аргумента, значение firsts теперь является списком этих первых элементов:
>>> firsts
[1.4, 1.5, 1.6, 1, 1.7, 1.4, 1.6]
В качестве альтернативы, вы также можете использовать понимание списка, чтобы написать то же самое другим способом:
>>> firsts = [sublist[0] for sublist in li1]
>>> firsts
[1.4, 1.5, 1.6, 1, 1.7, 1.4, 1.6]
Результатом сопоставления (в Python 2) и понимания списка является список, который сохраняется в памяти. Это не проблема для нашего небольшого списка li1
, но может стать проблемой для больших списков ввода. Поскольку мы хотим подсчитать значения только один раз, нам на самом деле не нужно их сохранять, и поэтому мы можем использовать выражение генератора (которое «вычисляет» каждое значение во времени):
>>> first = (sublist[0] for sublist in li1)
firsts
теперь это объект-генератор, из которого мы можем получить первые значения.
Теперь перейдем к подсчету. К счастью, Python 2.6 предоставляет Counter
класс, который мы можем использовать:
>>> import collections
>>> counter = collections.Counter(firsts)
>>> counter.most_common()
[(1.4, 2), (1.6, 2), (1.5, 1), (1.7, 1), (1, 1)]
Обратите внимание, что результат выражается в tupels, что, вероятно, в любом случае является тем, что вы хотите. Если вам действительно нужен список (например, потому что вы хотите что-то добавить к элементам), используйте map
для составления списка из каждого кортежа:
>>> map(list, counter.most_common())
[[1.4, 2], [1.6, 2], [1.5, 1], [1.7, 1], [1, 1]]
В общем, короткий способ записать все это:
import collections
a,b,c = 'abc'
li1 = [[1.4, b], [1.5, a], [1.6, c], [1,4, b], [1.7, c], [1.4, a], [1.6, c]]
li2 = collections.Counter(sublist[0] for sublist in li1).most_common()
Комментарии:
1. Это просто с
TypeError: unhashable type: 'list'
и близко не подходит к тому, что запрашивает OP (подсчет дубликатов).2. -1 Прочитайте еще раз, внимательно. Это все еще не выполняет то, что запрашивает OP. Он просто удаляет полностью повторяющиеся кортежи, вместо подсчета дублирующихся первых элементов.
3. @delnan обновлен решением, которое действительно учитывается, включая некоторое объяснение того, как и почему это работает, и использование
most_common
вместоitems
для получения результата, отсортированного по встречаемости.