2015-04-16 2 views
-1

Мне нужно получить индекс имени и номер учетной записи csv-файла.Поиск индекса множественного изменения строки

поэтому некоторые файлы могут выглядеть следующим образом

data = ['account number', 'first name'] 
or 
data = ['account #', 'First Name'] 
or 
data = ['ACCOUNT NUMBER', 'FIRST NAME'] etc. 
or 
data = ['...',.....,'account num',...,'firstname'] 

Так от того, что я нашел до сих пор (sackoverflow), я могу использовать l.index('first name'), чтобы получить индекс. Также, читая def (python tutorial), он, кажется, принимает только один параметр.

Любая идея, как я могу проверить индекс, если это любой из них?

+1

Переполненный мешок напоминает мне xmas :) – mhawke

+0

Не могли бы вы подробнее рассказать о своей проблеме? возможно, ожидаемый результат может помочь! – Kasramvd

+0

Имеет ли каждый файл CSV имена полей в первой строке файла? –

ответ

0

Вы можете использовать список понимание:

idx = [i for i, item in enumerate(data) if item.lower() == 'first name'] 

или более общо:

alist = ['first name', 'first name'] ## or ['account number', 'account #', ...] 
idx = [i for i, item in enumerate(data) if item.lower() in alist] 

Вы также можете использовать регулярные выражения для более сложных случаев:

import re 
idx = [i for i, item in enumerate(data) if re.search(pattern, item)] 
+0

, что о номере счета, где он может сказать, что «учетная запись №», может быть, может зависнуть или состояние там? если это возможно? –

0

Вы можете использовать re.match в виде перечня:

import re 
indices = [i for i,s in enumerate(data) if re.match(r'^(account.*)|(first\s?name)$',s,re.I)] 

В следующем регулярном выражении:

r'^(account.*)|(first\s?name)$ 

будет соответствовать любой строке, которые начинаются с account или любой строкой, которые начинаются с first и необязательным пробелом затем name также имеет Ignorecase флаг игнорировать в случае ваша строка.

0

Вот один из способов сделать это, используя наборы. Если ни одна строка не соответствует параметрам поля, то для его индекса возвращается -1, аналогично str.find().

#!/usr/bin/env python 

accnums = set(['account number', 'account #', 'account num', 'accnum']) 
firstnames = set(['first name', 'firstname', '1stname']) 

def find_fields(seq): 
    accnum, firstname = (-1, -1) 
    for i, field in enumerate(seq): 
     field = field.lower() 
     if field in accnums: 
      accnum = i 
     elif field in firstnames: 
      firstname = i 
    return accnum, firstname 

testdata = [ 
    ['account number', 'first name'], 
    ['account #', 'First Name'], 
    ['ACCOUNT NUMBER', 'FIRST NAME'], 
    ['accnum', '1stname'], 
    ['country', 'lastname', 'account num', 'account type', 'firstname'], 
    ['accnum', '1stname', 'account #'], 
    ['albatross', 'first name'], 
    ['Account Number', 'duck'], 
] 

for data in testdata: 
    print data, find_fields(data) 

выход

['account number', 'first name'] (0, 1) 
['account #', 'First Name'] (0, 1) 
['ACCOUNT NUMBER', 'FIRST NAME'] (0, 1) 
['accnum', '1stname'] (0, 1) 
['country', 'lastname', 'account num', 'account type', 'firstname'] (2, 4) 
['accnum', '1stname', 'account #'] (2, 1) 
['albatross', 'first name'] (-1, 1) 
['Account Number', 'duck'] (0, -1) 

Обратите внимание, что, если он находит несколько соответствующих записей для поля возвращает индекс соответствия поля последний. Таким образом, для ['accnum', '1stname', 'account #'] он возвращает 2 как индекс для номера номера счета.

Вы можете развернуть блок if: ... elif: в find_fields(), чтобы обрабатывать больше полей с различными именами, но если у вас много таких полей, тогда было бы лучше изменить логику так, чтобы она работала со списком множеств, а не с индивидуальные наборы.

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