#python
Вопрос:
Я пытаюсь подсчитать количество вхождений каждой строки в моем вложенном списке (на моем компьютере он намного больше, ниже приведен пример, демонстрирующий структуру).
lst = [[545300, ['sub10', 'sub13']], [546636, ['sub15', 'sub17']], [546648, ['sub15', 'sub17']], [8775, ['sub14', 'sub17']], [65, ['sub11', 'sub14']]] sh1 = 0 sh2 = 0 sh3 = 0 sh4 = 0 sh5 = 0 sh6 = 0 sh7 = 0 sh8 = 0 for pos, sampleList in lst: if 'sub10' in sampleList: sh1 = 1 elif 'sub11' in sampleList: sh2 = 1 elif 'sub12' in sampleList: sh3 = 1 elif 'sub13' in sampleList: sh4 = 1 elif 'sub14' in sampleList: sh5 = 1 elif 'sub15' in sampleList: sh6 = 1 elif 'sub16' in sampleList: sh7 = 1 elif 'sub17' in sampleList: sh8 = 1
Конечная цель:
суб10 | под11 | под12 | под13 | под14 | суб15 | суб16 | суб17 |
---|---|---|---|---|---|---|---|
1 | 1 | 0 | 1 | 2 | 2 | 0 | 2 |
Проблема в том, что значение «sub17» всегда равно 0, хотя при печати я вижу много экземпляров «sub17» в списке. Все остальные счетчики работают нормально, просто последний «элиф» не сработает.
Я тоже пытался:
for pos, sampleList in lst: if 'sub10' in sampleList: sh1 = 1 elif 'sub11' in sampleList: sh2 = 1 elif 'sub12' in sampleList: sh3 = 1 elif 'sub13' in sampleList: sh4 = 1 elif 'sub14' in sampleList: sh5 = 1 elif 'sub15' in sampleList: sh6 = 1 elif 'sub16' in sampleList: sh7 = 1 else: sh8 = 1
Я чувствую, что ответ, вероятно, является чем-то очевидным, и мне просто нужен свежий (или более продвинутый) взгляд, чтобы взглянуть на него.
Комментарии:
1. Почему бы вам не распечатать и не изучить
sampleList
в качестве первого оператора вfor
цикле, чтобы вы могли видеть, что происходит. Не полагайтесь на предположения, вместо этого выясните, какие значения содержатся в ваших переменных, что, я уверен, поможет вам понять, почему ваш код не делает то, что вы ожидаете/хотите.2. К вашему сведению, вам было бы лучше использовать списки, а не повторять все эти тесты if.
3. Вам нужны переменные
sh1
и т. Д…. или подойдет словарь , сопоставляющий имена, такие как «sub10», с числами?
Ответ №1:
С помощью collections.Counter
:
from collections import Counter res = Counter(sum(dict(lst).values(), [])) print(dict(res))
{'sub17': 3, 'sub15': 2, 'sub14': 2, 'sub10': 1, 'sub13': 1, 'sub11': 1}
Без collections.Counter
:
vals = sum(dict(lst).values(), []) res = dict.fromkeys(vals, 0) for val in vals: res[val] = 1 print(res)
{'sub17': 3, 'sub15': 2, 'sub14': 2, 'sub10': 1, 'sub13': 1, 'sub11': 1}
Ответ №2:
Используйте словарь, где ключи-это строка, которую вы считаете, а значения-это количество.
counts = {} for pos, sampleList in lst: for item in sampleList: # .get() returns the value at counts[item], and 0 if none exists # Then you increment this and save it to counts[item] counts[item] = counts.get(item, 0) 1
Таким образом, вам не придется жестко кодировать все if
операторы, и вам не придется иметь дело с множеством переменных.
В вашем примере lst
значение counts
равно:
{'sub10': 1, 'sub13': 1, 'sub15': 2, 'sub17': 3, 'sub14': 2, 'sub11': 1}
Чтобы получить доступ к количеству заданной строки, вы можете .get()
снова использовать:
print(counts.get("sub17", 0)) # Gives 3 print(counts.get("sub12", 0)) # Gives 0
Ответ №3:
Вы можете использовать collections.Counter
для подсчета значений. Вместо сложного набора геттеров и итераторов просто используйте простой цикл for.
import collections lst = [[545300, ['sub10', 'sub13']], [546636, ['sub15', 'sub17']], [546648, ['sub15', 'sub17']], [8775, ['sub14', 'sub17']], [65, ['sub11', 'sub14']]] counts = collections.Counter() for _, vals in lst: counts.update(vals)
Ответ №4:
Не используйте elif:
lst = [[545300, ['sub10', 'sub13']], [546636, ['sub15', 'sub17']], [546648, ['sub15', 'sub17']], [8775, ['sub14', 'sub17']], [65, ['sub11', 'sub14']]] sh1 = 0 sh2 = 0 sh3 = 0 sh4 = 0 sh5 = 0 sh6 = 0 sh7 = 0 sh8 = 0 for pos, sampleList in lst: if 'sub10' in sampleList: sh1 = 1 if 'sub11' in sampleList: sh2 = 1 if 'sub12' in sampleList: sh3 = 1 if 'sub13' in sampleList: sh4 = 1 if 'sub14' in sampleList: sh5 = 1 if 'sub15' in sampleList: sh6 = 1 if 'sub16' in sampleList: sh7 = 1 if 'sub17' in sampleList: sh8 = 1
Используя elif, вы просто проверяете наименьшее значение, которое появляется (поскольку вы заказали их таким образом), и sub17 всегда находится на второй позиции в вашем примере.
Комментарии:
1. О боже, спасибо тебе огромное, я думаю, что это решило проблему !