Получение значений из файла, если найдено совпадение для строк с одинаковым идентификатором в 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']})
Другие вопросы по тегам