Получение значений из файла, если найдено совпадение для строк с одинаковым идентификатором в Python
У меня есть файл со строками данных. Каждая строка начинается с идентификатора, за которым следует фиксированный набор атрибутов, разделенных запятой.
123,2,kent,...,
123,2,bob,...,
123,2,sarah,...,
123,8,may,...,
154,4,sheila,...,
154,4,jeff,...,
175,3,bob,...,
249,2,jack,...,
249,5,bob,...,
249,3,rose,...,
Я хотел бы получить атрибут, если условия выполнены. Условия, если 'bob' появляется в пределах того же идентификатора, получить значение второго атрибута, который следует.
For example:
id: 123
values returned: 2, 8
id: 249
values returned: 3
У Java есть двойной цикл, который я могу использовать, но я хотел бы попробовать это на Python. Любые предложения будут великолепны.
3 ответа
Я придумал (возможно) более питоническое решение, которое использует groupby
а также dropwhile
, Этот метод дает тот же результат, что и метод ниже, но я думаю, что он красивее...:) Флаги, "curr_id" и тому подобное не очень питонны, и их следует избегать, если это возможно!
import csv
from itertools import groupby, dropwhile
goal = 'bob'
ids = {}
with open('my_data.csv') as ifile:
reader = csv.reader(ifile)
for key, rows in groupby(reader, key=lambda r: r[0]):
matched_rows = list(dropwhile(lambda r: r[2] != goal, rows))
if len(matched_rows) > 1:
ids[key] = [row[1] for row in matched_rows[1:]]
print ids
(первое решение ниже)
from collections import defaultdict
import csv
curr_id = None
found = False
goal = 'bob'
ids = defaultdict(list)
with open('my_data.csv') as ifile:
for row in csv.reader(ifile):
if row[0] != curr_id:
found = False
curr_id = row[0]
if found:
ids[curr_id].append(row[1])
elif row[2] == goal:
found = True
print dict(ids)
Выход:
{'123': ['2', '8'], '249': ['3']}
Просто установите флаг или что-то еще, когда будете проходить:
name = 'bob'
id = '123'
found = False
for line in file:
l = line.split(',')
if l[0] == id:
if l[2] == name:
found = True
if found:
print l[1]
import csv, collections as co, cStringIO as StringIO
s = '''123,2,kent,...,
123,2,bob,...,
123,2,sarah,...,
123,8,may,...,
154,4,sheila,...,
154,4,jeff,...,
175,3,bob,...,
249,2,jack,...,
249,5,bob,...,
249,3,rose,...,'''
filelikeobject = StringIO.StringIO(s)
dd = co.defaultdict(list)
cr = csv.reader(filelikeobject)
for line in cr:
if line[2] == 'bob':
dd[line[0]]; continue
if line[0] in dd:
dd[line[0]].append(line[1])
Результат:
>>> dd
defaultdict(<type 'list'>, {'175': [], '123': ['2', '8'], '249': ['3']})