#python #csv
Суть данного скрипта в том, чтобы он вывел список значений из 2 файла, соответствующих значению id из первого файла. В итоге он выводит список лишь для самого первого id, а для остальных выдает пустой список "[ ]". Причем для каждого из этих id есть соответствующие значения, пустых списков там выводиться не должно. Что я не так делаю? posts_table = open("posts.csv") cat_rel_table = open("category_relationship.csv") reader_1 = csv.DictReader(posts_table) reader_2 = csv.DictReader(cat_rel_table) def cat_name(post_id): cat_list = [] for cat in reader_2: if cat['post_id'] == post_id: cat_list.append(cat['cat_id']) return cat_list for post in reader_1: if (post['type'] == "8" and post['status'] == "1"): print(post['id'], cat_name(post['id'])) вот пример содержимого posts.csv: "id","type","price","new_price","from_date","to_date","parent","created_at","author","featured","template","stock","view","status","barcode" "84","8","117","0","0000-00-00 00:00:00","0000-00-00 00:00:00","0","2017-10-12 14:37:38","1","../uploads/posts/2017/10/1-10-r-c-audi-r8-v10-compl-6v.jpg","0","10","0","2", "85","8","28","0","0000-00-00 00:00:00","0000-00-00 00:00:00","266","2017-10-12 17:41:45","1","../uploads/posts/2017/10/0011543346227-a.jpg","0","10","0","2", "86","8","13","0","0000-00-00 00:00:00","0000-00-00 00:00:00","266","2017-10-19 10:38:06","1","../uploads/posts/2017/10/81XHlhvCsJL._SL1500_.jpg","0","10","0","2", "87","8","28","0","0000-00-00 00:00:00","0000-00-00 00:00:00","266","2017-10-19 11:03:55","4","../uploads/posts/2017/10/cat-9-inch-big-builder-l&s-shaking-machine-vehicle-dump-truck--5AE442DA.zoom.jpg","0","10","0","1","11543346210" "88","8","28","0","0000-00-00 00:00:00","0000-00-00 00:00:00","0","2017-10-19 11:05:59","1","../uploads/posts/2017/10/pTRUCA1-22577036_alternate1_enh-z6.jpg","0","10","0","2", Пример category_relationship.csv "id","type","cat_id","post_id","status" "31","8","21","84","2" "32","8","21","85","2" "33","8","20","86","2" "34","8","21","86","2" "35","8","20","87","1" "36","8","21","87","2" "37","8","20","88","2" "38","8","21","88","2" Ожидаемый вывод: {131: ['2', '11', '43', '45', '72', '5', '8', '44']} (для каждого айдишника). Т.е. слева айдишник из первой таблицы, а справа список значений который скрипт получает из другой таблицы.
Ответы
Ответ 1
Вот теперь разобрался. У Вас, проблема в том, что конструкции open("category_relationship.csv") и csv.DictReader выдают объекты типа итератора, и после первого прохода курсор остается в конце, соответственно значений он более не возвращает, отсюда и пустой вывод при каждом следующем проходе. Для того, чтобы этого избежать, нужно считывать данные из файла для каждого прохода. Получается вот так: import csv posts = csv.DictReader(open("posts.csv")) def cat_list(post_id): return [item['cat_id'] for item in csv.DictReader(open("category_relationship.csv")) if item['post_id'] == post_id] di = {post['id']: cat_list(post['id']) for post in posts if post['type'] == "8" and post['status'] == "1"} # теперь словарь di можно использовать по своему усмотрению print(di) for key, val in di.items(): print(key, val) Решение на основе предложения топикстртера: import csv cat_file = open("category_relationship.csv") category = csv.DictReader(cat_file) posts = csv.DictReader(open("posts.csv")) # Поскольку здесь только один проход, скомбинируем. def cat_list(post_id): cat_file.seek(0) # Возвращаем курсор в начальное положение. return [item['cat_id'] for item in category if item['post_id'] == post_id] di = {post['id']: cat_list(post['id']) for post in posts if post['type'] == "8" and post['status'] == "1"} # теперь словарь можно использовать по своему усмотрению print(di) for key, val in di.items(): print(key, val)Ответ 2
Для подобных задач идеально подходит модуль Pandas: import pandas as pd # pip install pandas p = pd.read_csv(r'D:\temp\posts.csv') c = pd.read_csv(r'D:\temp\category_relationship.csv') res = (p.loc[(p['type']==8) & (p['status']==1), ['id']] .set_index('id') .join(c.groupby('post_id')['cat_id'] .apply(lambda x: x.values.tolist()))) результат: In [372]: p Out[372]: id type price new_price from_date ... template stock view status barcode 0 84 8 117 0 0000-00-00 00:00:00 ... 0 10 0 2 NaN 1 85 8 28 0 0000-00-00 00:00:00 ... 0 10 0 1 NaN 2 86 8 13 0 0000-00-00 00:00:00 ... 0 10 0 2 NaN 3 87 8 28 0 0000-00-00 00:00:00 ... 0 10 0 1 1.154335e+10 4 88 8 28 0 0000-00-00 00:00:00 ... 0 10 0 2 NaN [5 rows x 15 columns] In [373]: c Out[373]: id type cat_id post_id status 0 31 8 21 84 2 1 32 8 21 85 2 2 33 8 20 86 2 3 34 8 21 86 2 4 35 8 20 87 1 5 36 8 21 87 2 6 37 8 20 88 2 7 38 8 21 88 2 In [374]: res Out[374]: cat_id id 85 [21] 87 [20, 21] In [375]: res.to_dict()['cat_id'] Out[375]: {85: [21], 87: [20, 21]}
Комментариев нет:
Отправить комментарий