2014-09-25 3 views
11

Сценарий: у вас длинный кортеж в результате SQL-запроса и его нужно распаковать в отдельные значения. Каков наилучший способ сделать это, когда он соответствует PEP8? До сих пор у меня есть эти три варианта:Идиома для распаковки длинного кортежа

  1. одного задания, используйте обратную косую черту, чтобы разделить на несколько строк

    person_id, first_name, last_name, email, \ 
        birth_date, graduation_year, home_street, \ 
        home_city, home_zip, mail_street, mail_city, \ 
        mail_zip = row 
    
  2. одно назначение, группа левая сторона в скобках и разрывать строки без обратной косой черты

    (person_id, first_name, last_name, email, 
        birth_date, graduation_year, home_street, 
        home_city, home_zip, mail_street, mail_city, 
        mail_zip) = row 
    
  3. разделить на несколько назначений, каждый фитинг в одну линию

    person_id, first_name, last_name, email = row[0:4] 
    birth_date, graduation_year, home_street = row[4:7] 
    home_city, home_zip, mail_street, mail_city = row[7:11] 
    mail_zip = row[11] 
    

Какой из трех вариантов является лучшим? есть что-нибудь получше?

+3

Мнение. Мне не нравится решение с обратной косой чертой в конце строки, потому что код сломается, если после него будет невидимый символ (например, пробел). Для меня вторая версия - это путь. – Matthias

+2

Вы считали единый ['namedtuple'] (https://docs.python.org/2/library/collections.html#collections.namedtuple) вместо отдельных имен? – jonrsharpe

+3

@ Matthias Он спрашивает «в то время как соответствует PEP-8», и PEP-8 довольно подробно описывает, что использовать. – chepner

ответ

13

Отвечая на вопрос «Какой из трех вариантов является лучшим?»

pep8 состояния:

Предпочтительный способ упаковки длинных линий с использованием подразумеваемой строки продолжения Питона внутри скобок, скобки и фигурные скобки. Длинные строки могут быть разбиты на несколько строк, обертывая выражения в круглых скобках. Они должны использоваться вместо использования обратной косой черты для продолжения строки.

Это означает, что второй предпочтительнее первого. Третий тоже хорошо соответствует pep8, хотя лично не рекомендовал бы его.

+1

+1 Третий гораздо менее эффективен, и для выполнения той же задачи требуется гораздо больше байт-кодов. – chepner

5

Чтобы ответить «есть что-то лучше», я хотел бы предложить, что namedtuple позволяет получить доступ к отдельным элементам данных с минимальными усилиями:

>>> from collections import namedtuple 
>>> Person = namedtuple("Person", ['person_id', 'first_name', 'last_name', 
            'email', 'birth_date', 'graduation_year', 
            'home_street', 'home_city', 'home_zip', 
            'mail_street', 'mail_city', 'mail_zip']) 
>>> row = range(12) # dummy data 
>>> p = Person(*row) # unpack tuple into namedtuple 
>>> p 
Person(person_id=0, first_name=1, last_name=2, email=3, birth_date=4, graduation_year=5, home_street=6, home_city=7, home_zip=8, mail_street=9, mail_city=10, mail_zip=11) 
>>> p.birth_date 
4 

Это означает, что вы доступ к атрибутам, а не отдельные имен , но имеет меньший вес, чем создание класса, сохраняет все данные из вашего запроса вместе и предоставляет значения через разумные имена.

+0

Это выглядит прекрасно, если вам нужно сделать это несколько раз для той же последовательности атрибутов. Однако, если вы знаете, что вы не будете распаковывать такую ​​строку в более чем одном месте, это, вероятно, слишком тяжеловес (вместо одного или нескольких назначений вам нужно импортировать коллекцию, определить именованный кортеж и т. Д. Только для одного распаковка). – koniiiik

+0

@koniiiik за документы, 'namedtuple's *" не требуют больше памяти, чем обычные кортежи "*. Определение контейнера имеет ту же длину, что и текущая распаковка, поэтому вы добавляете только две строки ('import' и unpack). Если вы уверены, что сможете использовать его только один раз, вы можете быть правы. – jonrsharpe

+1

Ну, по крайней мере, он состоит из более не простых тривиальных шагов, которые могут сделать его менее очевидным, что происходит.Но опять же, зависит от конкретной ситуации. – koniiiik

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