Ошибки возникают о функции словаря в Python - PullRequest
0 голосов
/ 06 октября 2011

Часть моего скрипта на python: (я сначала сделал словарь "h")

def histogram(L):
    d= {}
    for x in L:
       if x in d:
          d[x] +=1
       else:
          d[x] =1
    return d
h=histogram(LIST)

for vhfile in vhfiles:
    linelist=commands.getoutput('cat ' + vhfile).splitlines(True)
    list1=[]
    for line in linelist:
        name1 = line.split()[0]
        if int(h[name1]) <= 300:
           list1.append(line)

Затем я получил ошибку в строке "if":

File "/home/xug/scratch/mrfast/NA12878/dis_rm.py", line 51, in <module>
    if int(h[name1]) <= 300:
KeyError: '080821_HWI-EAS301_0002_30ALBAAXX:1:46:1643:1310'

Есть идеиздесь произошло?ТНХ

Ответы [ 2 ]

3 голосов
/ 06 октября 2011

Вы получаете KeyError, когда пытаетесь найти что-то в dict, а dict не содержит этот ключ.

В этом случае кажется, что ключ '080821_HWI-EAS301_0002_30ALBAAXX:1:46:1643:1310' не встречается в h.

2 голосов
/ 06 октября 2011

Ошибка ключа означает, что вы указали ключ в вашем слове, который не существует. Произошла ошибка при получении значения по указанному ключу, поскольку ключ не существует.

Один из способов справиться с этим - использовать блок try / исключением. Если код в «try» вызывает «KeyError», вы знаете, что name1 не было в h, и вы можете делать все что угодно.

for line in linelist:
    name1 = line.split()[0]
    try:
        if int(h[name1]) <= 300:
           list1.append(line)
    except KeyError:
         <code here to deal with the condition>

Эта методология предпочтения обработки исключений над повсеместным использованием проверки «если» известна в сообществе Python как «EAFP» (проще просить прощения, чем разрешения).

Вы также можете (используя меньше средств Pythonic) проверить, присутствует ли name1 в списке, прежде чем ссылаться на него:

if name1 in h:
    if int(h[name1]) <= 300:
       ... you get the idea

Эта методология называется «Смотри, прежде чем прыгнуть» (LBYL). EAFP, как правило, предпочтительнее в целом.

Кроме того, вам даже не нужна функция гистограммы. В Python 2.7 есть объект Counter, который делает это за вас:

>>> LIST = "This is a sentence that will get split into multiple list elements. The list elements will get counted using defaultdict, so you don't need the histogram function at all.".split()    
>>> LIST
['This', 'is', 'a', 'sentence', 'that', 'will', 'get', 'split', 'into', 'multiple', 'list', 'elements.', 'The', 'list', 'elements', 'will', 'get', 'counted', 'using', 'defaultdict,', 'so', 'you', "don't", 'need', 'the', 'histogram', 'function', 'at', 'all.']    
>>> from collections import Counter    
>>> c = Counter(LIST)
>>> c
Counter({'get': 2, 'list': 2, 'will': 2, 'defaultdict,': 1, 'elements.': 1, "don't": 1, 'is': 1, 'at': 1, 'need': 1, 'sentence': 1, 'split': 1, 'you': 1, 'into': 1, 'function': 1, 'elements': 1, 'multiple': 1, 'that': 1, 'This': 1, 'histogram': 1, 'using': 1, 'The': 1, 'a': 1, 'all.': 1, 'so': 1, 'the': 1, 'counted': 1})

До версии 2.7 вы можете использовать defaultdict для получения того же результата:

>>> from collections import defaultdict
>>> dd = defaultdict(int)
>>> for word in LIST:
...     dd[word] += 1
... 
>>> dd
defaultdict(<type 'int'>, {'defaultdict,': 1, 'elements.': 1, "don't": 1, 'is': 1, 'at': 1, 'need': 1, 'sentence': 1, 'split': 1, 'get': 2, 'you': 1, 'into': 1, 'function': 1, 'elements': 1, 'multiple': 1, 'that': 1, 'This': 1, 'histogram': 1, 'using': 1, 'The': 1, 'a': 1, 'all.': 1, 'list': 2, 'will': 2, 'so': 1, 'the': 1, 'counted': 1})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...