2014-02-19 3 views
0

У меня есть код, который генерирует список из 28 словарей. Он циклически проходит через 28 файлов и связывает точки данных с каждым файлом в соответствующем словаре. Для того, чтобы сделать мой код более гибким, я хотел бы использовать:Создание списка словарей

tegDics = [dict() for x in range(len(files))] 

Но когда я запускаю код первые 27 словарей являются пустыми и только последние, tegDics [27], имеет данные. Ниже приведен код, в том числе и неуклюжий, но функциональный, код мне приходится использовать, что формирует словари:

x=0 
import os 
files=os.listdir("DirPath") 
os.chdir("DirPath") 
tegDics = [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}] # THIS WORKS!!! 
#tegDics = [dict() for x in range(len(files))] - THIS WON'T WORK!!! 
allRads=[] 
while x<len(tegDics): # now builds dictionaries 
    for line in open(files[x]): 
     z=line.split('\t') 
     allRads.append(z[2]) 
     tegDics[x][z[2]]=z[4] # pairs catNo with locNo 
    x+=1 

Кто-нибудь знает, почему более элегантный код не работает.

ответ

6

Поскольку вы используете x в понимании списка, он не будет равен нулю к тому времени, когда вы достигнете цикла while - вместо этого оно будет len(files)-1. Я предлагаю изменить переменную, которую вы используете для чего-то другого. Традиционно использовать один знак подчеркивания для значения, которое вам неинтересно.

tegDics = [dict() for _ in range(len(files))] 

Это может быть полезно, чтобы исключить использование вами x полностью. В python принято использовать итерацию непосредственно над объектами в последовательности, вместо использования переменной счетчика. Вы могли бы сделать что-то вроде:

for tegDic in tegDics: 
    #do stuff with tegDic here 

Хотя это немного сложнее в вашем случае, так как вы хотите, чтобы одновременно перебирать tegDics и files одновременно. Вы можете использовать zip для этого.

import os 
files=os.listdir("DirPath") 
os.chdir("DirPath") 
tegDics = [dict() for _ in range(len(files))] 
allRads=[] 
for file, tegDic in zip(files,tegDics): 
    for line in open(file): 
     z=line.split('\t') 
     allRads.append(z[2]) 
     tegDic[z[2]]=z[4] # pairs catNo with locNo 
+0

Хорошая находка! Я пропустил, что 'х' был повторно использован. Вы должны научить OP о '' для каждого 'типа петель Python, а также с помощью 'enumerate()' или 'zip()'. –

+0

Не знал о _ конвенции, предположим, что немного опасно смешиваться с привычками gettext, но – deinonychusaur

+0

Не стесняйтесь оторваться от конвенции, если вы беспокоитесь о подобных миксах. Мне также нравится использовать переменную 'i' как мою ', которая никогда не используется ничем, кроме циклов диапазона. – Kevin

-2

Во всяком случае есть простой способ имхо:

taegDics = [{}]*len(files) 
+4

Это имеет удивительный эффект. Если вы попробуете 'dicts = [{}] * 2; dicts [0] [0] = 99; print dicts', вы увидите, что словари _both_ имеют запись '99', хотя вы ее только установили! – Kevin

+0

Черт! это очень плохо. Спасибо за ваше предупреждение. – salvo

Смежные вопросы