2014-11-18 4 views
1

Я нахожу, что пишу код, как показано ниже. Это очень много. То, что я хотел бы сделать, это назначить индексы массива для разных переменных, а если есть indexerror, присвойте false. Я чувствую, что для этого должен быть более короткий синтаксис (по сравнению с тем, что у меня ниже).Как заменить несколько блоков try/except с меньшим количеством кода?

Редактировать - вот мой фактический код. page - действительный объект lxml.html. Каждый из селекторов может или не может возвращать значение, в зависимости от того, присутствует ли этот раздел на странице.

def extract_data(page): 
    # given lxml.html obj, extract data from g+ page and return as dict 
    try: 
     profile_name = page.xpath('//div[@guidedhelpid="profile_name"]/text()')[0] 
    except IndexError: 
     profile_name = False 
    try: 
     website = page.cssselect('span.K9a')[0].text_content().rstrip('/') 
    except IndexError: 
     website = False 

    try: 
     contact_div = html.tostring(page.xpath('//div[normalize-space(text())="Contact Information"]/../../..')[0]) 
    except IndexError: 
     contact_div = False 

    return { 
     'profile_name'  : profile_name, 
     'website'   : website, 
     'contact_div'  : contact_div, 
    } 
+0

несвязанные предложения: 'лист (1,2)' должен быть '[1, 2]' и никакая переменная не должна называться 'L' (если вы действительно хотите одной буквы L, используйте' L' вместо). См. Http://www.python.org/dev/peps/pep-0008/ – ThiefMaster

+0

О вашем фактическом вопросе: что вы пытаетесь сделать? Поскольку речь идет о lxml, возможно, есть более чистый способ сделать то, что вы пытаетесь сделать ... – ThiefMaster

+0

@ travis-leleu, вам действительно нужен доступ ко всем элементам списка за один раз? Как правило, вы обрабатываете элементы из списка по одному, в этом случае код будет 'для элемента в L: do_something (item)' – vikramls

ответ

1
vars = ['first', 'second', 'third'] 
r = {} 
for i, var in enumerate(vars): 
    try: 
     r[var] = l[i] 
    except IndexError: 
     r[var] = False 
3

Предполагая, что вы пытаетесь сделать, имеет смысл в контексте вашего случая использования, вы можете инкапсулировать это понятие значения по умолчанию внутри функции:

def retrieve(my_list, index, default_value=False): 
    try: 
     return my_list[index] 
    except IndexError: 
     return default_value 

Таким образом, вы можете сделать что-то вроде:

my_list = [2, 4] 
first = retrieve(my_list, 0) 
# first will be 2 
second = retrieve(my_list, 1) 
# second will be 4 
third = retrieve(my_list, 2) 
# third will be False 

Вы можете даже изменить значение, которое вы хотели бы использовать по умолчанию, если индекс делает n существует.

В целом, когда вы повторяете код, как описано выше, первое, о чем вы должны подумать, - это написать ли вы функцию, которая делает то, что вы пытаетесь сделать.


Использование фактического кода, вы могли бы сделать что-то вроде:

profile_name = retrieve(page.xpath('//div[@guidedhelpid="profile_name"]/text()'), 0) 
website = retrieve(page.cssselect('span.K9a'), 0) 
if website: 
    website = website.text_content().rstrip('/') 
contact_div = retrieve(page.xpath('//div[normalize-space(text())="Contact Information"]/../../..'), 0) 
if contact_div: 
    contact_div = html.tostring(contact_div) 
+0

Я бы сделал по умолчанию 'None' вместо' False'. И вы всегда можете вернуть * два * значения, а второй - указать, действительно ли значение. –

+0

Да, я согласен с вами в том, что «False» является плохим значением по умолчанию, но я не буду предполагать, чтобы узнать, какой вариант использования OP находится вне того, что указано в проблеме. – huu

+0

Я обновил q с помощью своего фактического кода, возможно, теперь это будет иметь больше смысла. Почему я должен использовать None вместо False? –

0

Это должно решить вашу проблему :) Exec + зацикливание на помощь!

l = list([0,2]) 

numberWords = { 0:"first", 1:"second", 2:"third"} 

for i in range(0,len(l)): 
    try: 
     exec(numberWords[i]+"=l["+str(i)+"]") 
    except IndexError: 
     exec(numberWords[i]+"=false") 
Смежные вопросы