Для цикла, который не будет сохранять значения счетчика

#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. О боже, спасибо тебе огромное, я думаю, что это решило проблему !