LINUX.ORG.RU

python посоветуйте тип данных

 


0

1

есть zip архивы, нужно получить список уникальных файлов в них, а потом что то с ними сделать
я использую infolist() и хеширую в md5 CRC+file_size (в md5 просто для одинаковой длины)
ок, теперь у меня есть хеш, который удобно делать ключом словаря, чтоб проверять на уникальность. но нужна информация, как эти файлы открыть
значение словаря я попробовал писать path_to_zip:filename
выходит

{'53815633de62ce94e36a43a8bb93be7e': '/path/zipfile.zip:contentfile2.txt', 
 '5ca906d1e42de7d6859b320502ff9317': '/path/zipfile.zip:contentfile.txt',
 '1fb71abf56c03621d971c1883a273e9c': '/path/zipfile1.zip:contentfile3.txt'}
теперь можно итерируясь по словарю, делать split(':') и всё работает. только это уродство.
не говоря уже о том, что это больше похоже на тест жестких дисков по рандомному чтению
хочу возможность сгруппировать пути до zip файлов, чтоб отрыл один раз, прочёл список всех contentfile[n..].txt и закрыл
пример:
{'/path/zipfile.zip': ['contentfile2.txt', 'contentfile.txt'],
 '/path/zipfile1.zip': ['contentfile3.txt']}
как лучше готовить первый словарь с хешами, чтоб потом из него можно было легко сделать то, что в примере?

UPD: что сделать с data, чтоб не городить такой фигни, а как то элегантнее, может есть хитрые sets или reduce?

data= {'53815633de62ce94e36a43a8bb93be7e': '/path/zipfile.zip:contentfile2.txt', 
 '5ca906d1e42de7d6859b320502ff9317': '/path/zipfile.zip:contentfile.txt',
 '1fb71abf56c03621d971c1883a273e9c': '/path/zipfile1.zip:contentfile3.txt'}

new_data = {}

for i in data:
	path = data[i].split(':')[0]
	fname = data[i].split(':')[1]
	if path not in new_data:
		new_data[path] = list()
	new_data[path].append(fname)

print new_data
★★★★★

Последнее исправление: system-root (всего исправлений: 1)

Ну сделай такой словарь

{
  'hash1': {
             'path': '/tmp/file1.zip',
             'filename': 'contentfile1.txt'
           },
  'hash2': {
             'path': '/tmp/file2.zip',
             'filename': ['contentfile2.txt', 'contentfile3.txt']
           }
}
alozovskoy ★★★★★
()
Последнее исправление: alozovskoy (всего исправлений: 1)

теперь можно итерируясь по словарю, делать split(':') и всё работает. только это уродство.

Может использовать json для хранения сего добра в файлах?

json.dumps и json.loads

Siado ★★★★★
()
Последнее исправление: Siado (всего исправлений: 1)
Ответ на: комментарий от Siado

не понял какого добра? то, что уже есть, я храню через pickle
суть вопроса в том, как создавать записи, чтоб потом из них получить то, что на желаемом примере, без 100500 циклов for
т.е. из словаря, в котором ключ это хеш, а значение это некий тип данных который я ищу, получить словарь, в котором ключ - это адрес до zip архива, а значение это список всех его файлов.

system-root ★★★★★
() автор топика
Ответ на: комментарий от system-root

Еще меньше стало понятно. Чем не устраивает «словарь, в котором ключ - это адрес до zip архива, а значение это список всех его файлов»?

anonymous
()
Ответ на: комментарий от anonymous

я наверное не очень понятно излагаю свои мысли в теме, в которой мало разбираюсь
но «Чем не устраивает» никак не уместно к,

суть вопроса в том как [...] получить словарь, в котором ключ - это адрес до zip архива, а значение это список всех его файлов.

system-root ★★★★★
() автор топика
Ответ на: комментарий от system-root

не понял какого добра? то, что уже есть, я храню через pickle

Ну ты же делаешь split(':'), поэтому я предположил что ты парсишь текстовый файл, чтобы вытянуть оттуда данные.

а значение это некий тип данных который я ищу, получить словарь, в котором ключ - это адрес до zip архива, а значение это список всех его файлов.

Ну может тогда, как засоветовал alozovskoy?

Siado ★★★★★
()
Ответ на: комментарий от Siado

поэтому я предположил что ты парсишь текстовый файл

не файл, а строку '/path/zipfile.zip:contentfile2.txt'

Ну может тогда, как засоветовал alozovskoy?

он предположил, что в hash2 я уже могу записать два файла, но ведь - один хеш, один файл, одна запись в словаре.
в UPD я наглядно показал, что происходит. нужно сделать «len(data)*2» split(':'), а потом ещё «len(data)*1» append(fname)
это херово. почти 1млн операций просто потому, что я не знаю как лучше

system-root ★★★★★
() автор топика
Ответ на: комментарий от system-root

А как у тебя вообще получились такие строки '/path/zipfile.zip:contentfile2.txt' ?

Ради интереса сейчас проверил стандартную библиотеку (zipfile), не вижу где взять инфо о файле именно в таком формате. За-то вижу замечательный метод «namelist()», который выдает список всех файлов массива. Т.е. можно на основе этого листа собрать необходимый словарь формата { 'hash':{'path/fname.zip':[files]}

Siado ★★★★★
()

Вместо вот этого:

if path not in new_data:
	new_data[path] = list()
new_data[path].append(fname)

Можно делать так:

new_data.setdefault(path,[]).append(fname)
Siado ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.