2014-11-11 3 views
0

У меня есть словарь с 400 000 элементов в нем, чьими ключами являются имена ДНК и значения - последовательности ДНК. Я хочу разделить словарь на 40 текстовых файлов с 10 000 элементов в каждом из файлов.Как написать несколько файлов из словаря в python

Вот мои коды:

record_dict # my DNA dictionary 

keys_in_dict #the list of the keys 

for keys in keys_in_dict: 

    outhandle = open("D:\\Research\\Transcriptome_sequences\\input{0}.fasta".format (?????), "w") 

Что я должен поставить на место (?????)? Как закончить этот цикл?

ОБНОВЛЕНИЕ: Привет, ребята, Благодарим за помощь. Теперь я могу сделать несколько файлов из словаря. Однако, когда я пытался сделать несколько файлов непосредственно из исходного файла, вместо того чтобы сначала сделать словарь, у меня были проблемы. Коды генерируют только один файл с первым элементом в нем. Что я сделал не так? Вот мои коды:

from Bio import SeqIO 
handle = open("D:/Research/Transcriptome_sequences/differentially_expressed_genes.fasta","rU") 

filesize = 100  # number of entries per file 
filenum = 0 
itemcount = 0 


for record in SeqIO.parse(handle, "fasta") : 
    if not itemcount % filesize: 
     outhandle = open("D:/Research/Transcriptome_sequences/input{0}.fasta".format(filenum), "w") 
     SeqIO.write(record, outhandle, "fasta") 
     filenum += 1 
     itemcount += 1  
outhandle.close() 
+0

Вы только спрашиваете, как получить значение, соответствующее каждой клавише «ключи»? Это просто 'record_dict [keys]'. (Именовать переменную, которая содержит каждый ключ, по одному за раз, поскольку множественные «ключи» кажутся вводящими в заблуждение ...) – abarnert

+0

В качестве примечания вам почти не нужен список ключей словаря; вы можете просто перебрать 'для ключа в record_dict:'. Или вы можете зациклиться на 'для ключа, значение в record_dict.items():' и не нужно делать 'record_dict [key]' внутри цикла. – abarnert

+0

Спасибо, abarnert. Проще говоря, у меня есть большой файл с 400 000 элементов в нем, и я хочу разделить этот файл на 40 файлов меньшего размера с 10 000 наименований в каждом маленьком файле. – Gray

ответ

0

Это не будет самым быстрым решением, но я думаю, что самый straightforwared способ следить за линиями и откройте файл каждые 10000 итераций через петлю.

Я предполагаю, что вы пишете fasta или еще что-то.

В противном случае вы можете предварительно нарезать список [:10000] и создать кусок вывода, чтобы написать все сразу с помощью одной команды (что было бы намного быстрее). Даже если это так, вам может понадобиться создать строку, объединив ее через цикл, а затем создав одну чудовищную строку с помощью одной команды .write для каждого файла.

itemcount=0 
filesize = 10000 
filenum = 0 
filehandle = "" 

for keys in keys_in_dict: 
    # check if it is time to open a new file, 
    # whenever itemcount/filesize has no remainder 
    if not itemcount % filesize: 
     if filehandle: 
      filehandle.close() 
     filenum+=1 
     PathToFile = "D:/Research/Transcriptome_sequences/input{0}.fasta".format(filenum) 
     filehandle = open(PathToFile,'w') 
    filehandle.write(">{0}\n{1}\n".format(keys,record_dict[keys]) 
    itemcount += 1 

filehandle.close() 

EDIT: Вот более эффективный способ сделать это (время-накрест, а не памяти мудрым), только писать один раз в файл (40x общего), а не с каждой строки (400000 раз) , Как всегда, проверьте свой вывод, особенно убедитесь, что первая и последняя последовательности включены в вывод, и последний файл написан правильно.

filesize = 10  # number of entries per file 
filenum = 0 
filehandle = "" 
OutString = "" 

print record_dict 
for itemcount,keys in enumerate(keys_in_dict): 
    # check if it is time to open a new file, 
    # whenever itemcount/filesize has no remainder 
    OutString += ">{0}\n{1}\n".format(keys,record_dict[keys]) 
    if not itemcount % filesize: 
     if filehandle: 
      filehandle.write(OutString) 
      filehandle.close() 
      OutString ="" 
     filenum+=1 
     PathToFile = "D:/Research/Transcriptome_sequences/input{0}.fasta".format(filenum) 
     filehandle = open(PathToFile,'w') 


filehandle.write(OutString) 
filehandle.close() 
+0

Правильно. Я пишу быстрый формат. Другой вопрос: полный порядковый номер не может быть целым числом. Это может быть 399, xxx что-то. – Gray

+0

Он говорит, что дескриптор файла не определен. Должен ли я перемещать строку дескриптора файла до строки ifhandhandle? – Gray

+0

Что я помещаю в файлhandle.write ("OUTPUT TEXT HERE \ n")? Он создает каждый файл для каждого моего гена. – Gray

1
n = 10000 
sections = (record_dict.items()[i:i+n] for i in xrange(0,len(record_dict),n)) 
for ind, sec in enumerate(sections): 
    with open("D:/Research/Transcriptome_sequences/input{0}.fasta".format(ind), "w") as f1: 
     for k,v in sec: 
      f1.write("{} {}\n".format(k,v)) 
+0

Большое вам спасибо, Padraic. Я сейчас пытаюсь. – Gray

+0

Разве это не просто выписывает каждый 10 000-й предмет, а не остальные? – beroe

+0

В нем говорится, что аргументы «writelines() должны быть последовательностью строк» ​​ – Gray

0

Используя встроенный модуль/функции, itertools.tee, может решить эту проблему элегантно.

import itertools 

for (idx, keys2) in enumerate(itertools.tee(keys_in_dict, 40)): 
    with open('filename_prefix_%02d.fasta' % idx, 'w') as fout: 
     for key in keys2: 
      fout.write(...) 

Цитируется по документу для справки:

itertools.tee (итерируемый [, п = 2]) Возврат п независимых итераторы от А одного итерации.

После того, как тройник() сделал раскол, исходный итерируемый не должен использоваться в другом месте; в противном случае, итерабельность могла бы быть продвинута без уведомлений об объектах tee .

Для этого может потребоваться значительное вспомогательное хранилище (в зависимости от , сколько временных данных необходимо сохранить). В общем случае, если один итератор использует большинство или все данные перед запуском другого итератора, быстрее использовать список() вместо tee().

+0

Nice, Drake. Другой способ сделать это. Очень просветитель! – Gray

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