2014-10-26 4 views
0

У меня есть список списков, и я знаю каждый тип элементов [Str, Str, Str, Int, Int, Int, Str, Int]. У меня есть функция новообращенного, которая угадывает тип:типы преобразования элементов повторного списка

def convert(val): 
    constructors = [int, str] 
    for c in constructors: 
     try: 
      return c(val) 
     except ValueError: 
      pass 

Как это можно заменить функцию преобразования, потому что я знаю, тип каждого элемента (смотрите ниже полный код)?

from __future__ import absolute_import, division, print_function 
from itertools import groupby 


DATA = [["Test", "A", "B01", 828288, 1, 7, 'C', 5], 
     ["Test", "A", "B01", 828288, 1, 7, 'T', 6], 
     ["Test", "A", "B01", 171878, 3, 7, 'C', 5], 
     ["Test", "A", "B01", 171878, 3, 7, 'T', 6], 
     ["Test", "A", "B01", 871963, 3, 9, 'A', 5], 
     ["Test", "A", "B01", 871963, 3, 9, 'G', 6], 
     ["Test", "A", "B01", 1932523, 1, 10, 'T', 4], 
     ["Test", "A", "B01", 1932523, 1, 10, 'A', 5], 
     ["Test", "A", "B01", 1932523, 1, 10, 'X', 6], 
     ["Test", "A", "B01", 667214, 1, 14, 'T', 4], 
     ["Test", "A", "B01", 667214, 1, 14, 'G', 5], 
     ["Test", "A", "B01", 667214, 1, 14, 'G', 6]] 


def convert(val): 
    constructors = [int, str] 
    for c in constructors: 
     try: 
      return c(val) 
     except ValueError: 
      pass 


def main(): 
    with open("/home/mic/tmp/test.txt") as f: 
     for line in f: 
      try: 
       data = [convert(part.strip()) for part in line.split(',')] 
       print(data) 
      except IndexError: 
       continue 

UPDATE Спасибо за все ответы, которые дали мне новые идеи, и поэтому я изменил код (Метод 1 - 4), который в настоящее время не работает:

#!/usr/bin/env python 
from __future__ import absolute_import, division, print_function 
from itertools import groupby 
import csv 

parts = [["Test", "A", "B01", 828288, 1, 7, 'C', 5], 
     ["Test", "A", "B01", 828288, 1, 7, 'T', 6], 
     ["Test", "A", "B01", 171878, 3, 7, 'C', 5], 
     ["Test", "A", "B01", 171878, 3, 7, 'T', 6], 
     ["Test", "A", "B01", 871963, 3, 9, 'A', 5], 
     ["Test", "A", "B01", 871963, 3, 9, 'G', 6], 
     ["Test", "A", "B01", 1932523, 1, 10, 'T', 4], 
     ["Test", "A", "B01", 1932523, 1, 10, 'A', 5], 
     ["Test", "A", "B01", 1932523, 1, 10, 'X', 6], 
     ["Test", "A", "B01", 667214, 1, 14, 'T', 4], 
     ["Test", "A", "B01", 667214, 1, 14, 'G', 5], 
     ["Test", "A", "B01", 667214, 1, 14, 'G', 6]] 


def iter_something(rows): 
    key_names = ['type', 'name', 'sub_name', 'pos', 's_type', 'x_type'] 
    chr_key_names = ['letter', 'no'] 
    for keys, group in groupby(rows, lambda row: row[:6]): 
     result = dict(zip(key_names, keys)) 
     result['chr'] = [dict(zip(chr_key_names, row[6:])) for row in group] 
     yield result 


def main(): 
    #Method 1 
    converters = [str, str, str, int, int, int, str, int] 
    with open("/home/mic/tmp/test.txt") as f: 
     parts = (line.strip().split(',') for line in f) 
     column = (con(part) for con, part in zip(converters, parts)) 
     for object_ in iter_something(column): 
      print(object_) 

    #Method 2 
    with open("/home/mic/tmp/test.txt") as f: 
     parts = (line.strip().split(',') for line in f) 
     parts[3], parts[4], parts[5], parts[7] = int(parts[3]),\ 
               int(parts[4]),\ 
               int(parts[5]),\ 
               int(parts[7]) 
     column = (con(part) for con, part in zip(converters, parts)) 
     for object_ in iter_something(column): 
      print(object_) 

    #Method 3 
    converters = [str, str, str, int, int, int, str, int] 
    with open("/home/mic/tmp/test.txt", 'rb') as f: 
     reader = csv.reader(f, skipinitialspace=True) 
     for object_ in iter_something(reader): 
      print(object_) 

    #Method 4 
    with open("/home/mic/tmp/test.txt", 'rb') as f: 
     reader = csv.reader(f, skipinitialspace=True) 
     reader[3], reader[4], reader[5], reader[7] = int(reader[3]),\ 
                int(reader[4]),\ 
                int(reader[5]),\ 
                int(reader[7]) 

     for object_ in iter_something(reader): 
      print(object_) 


if __name__ == '__main__': 
    main() 
+0

что тип каждого элемента и то, что вы хотите конвертировать функция делать? –

+0

converters = [str, str, str, int, int, int, str, int] – user977828

+0

, поэтому вы хотите удалить try и cast, потому что вы знаете, что структура всегда будет str, str, str, int, int, int, str, int? –

ответ

2

Вы можете использовать zip() в паре типа с колонкой:

converters = [str, str, str, int, int, int, str, int] 

for line in f: 
    data = [convert(part.strip()) 
      for convert, part in zip(converters, line.split(','))] 

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

parts = (line.strip().split(',') for line in f) 
column = ([con(col) for con, col in zip(converters, row)] for row in parts) 

Могу ли я вновь заявить, учитывая, используя csv module еще раз, как я сделал для previous question? Вы изобретая CSV-парсинга колесо немного здесь:

with open("/home/mic/tmp/test.txt") as f: 
    reader = csv.reader(f, skipinitialspace=True) 
    converted = ([conv(col) for conv, col in zip(converters, row)] for row in reader) 
+0

да, вы можете повторить рассмотрение использования модуля csv. Есть ли разница в производительности между модулем csv и line.split (',')? – user977828

+0

@ user977828: Модуль CSV закодирован на языке C и добавляет такие функции, как правильная обработка цитированных столбцов (включая использование разделителя и новых строк в значениях столбцов) и т. Д. Это будет быстрее, чем использование разделения и понимание списка. –

+0

это похоже на другой ответ на самом деле не отвечает на вопрос –

2

Учитывая список constructors, как вы описали в начале вашего вопроса, вы можете сделать это:

reader = csv.reader(f) 
data = [[con(val) for con, val in zip(constructors, line)] for line in reader] 

Это даст вам двумерный список; которая является структурой, которую вы хотели судить по коду, который вы предоставили.


EDIT: Я изменил решение для работы с модулем csv, который вам нужно будет импортировать в верхней части. Вышеприведенный код, конечно же, войдет в ваш оператор with.

+0

Я обновил свой вопрос выше – user977828

+0

@ user977828 Я не совсем понимаю обновление. Что еще нужно сделать решению? –

+0

Ваш ответ на самом деле работает с 'iter_something', но я был кариозен, как он будет работать с модулем' csv', а также с решением @Padraic Cunningham. – user977828

1

Я попробую на самом деле ответить на ваш вопрос, вы спросили:

Как элементы уже натягивает вы просто должны бросить РАСЧ:

data = ["Test", "A", "B01", "667214", "1", "14", 'G',"6"] 

data[3], data[4], data[5], data[7],= int(data[3]),int(data[4]), int(data[5]), int(data[7]) 

Так ваш главный будет выглядеть как:

def main(): 
    with open("/home/mic/tmp/test.txt") as f: 
     for line in f: 
      try: 
       data = [part.strip() for part in line.split(',')] 
       data[3], data[4], data[5], data[7],= int(data[3]),int(data[4]), int(data[5]), int(data[7]) 
      except IndexError: 
       continue 

Но поскольку вы уже используете попытку, было бы лучше добавить исключение для ValueError

except (IndexError,ValueError):

Вам не нужна функция преобразования, отбрасывая, как Интс в вашем главном будет достаточно, никаких точек литейных строк, которые уже не натягивает

+0

Я обновил свой вопрос выше – user977828

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