2013-02-21 4 views
7

Aus der Dokumentation entnommen, ist das Folgende ein Ausschnitt, der zeigt, wie die Regex-Methode findall funktioniert, und bestätigt, dass es eine Liste zurückgibt.Python: Regex findall gibt eine Liste zurück, warum gibt der Versuch, auf das Listenelement [0] zuzugreifen, einen Fehler zurück?

re.findall(r"\w+ly", text) 
['carefully', 'quickly'] 

jedoch das folgende Codefragment einen außerhalb der Grenzen Fehler erzeugt (IndexError: list index out of range), wenn das nullte Element der Liste von zurück findall zuzugreifen versuchen.

Relevante Codefragment:

population = re.findall(",([0-9]*),",line) 
x = population[0] 
thelist.append([city,x]) 

Warum passiert das das?

Für etwas mehr Hintergrund ist hier, wie das Fragment in mein ganzes Skript passt:

import re 

thelist = list() 
with open('Raw.txt','r') as f: 
    for line in f: 
     if line[1].isdigit(): 
      city = re.findall("\"(.*?)\s*\(",line) 
      population = re.findall(",([0-9]*),",line) 
      x = population[0] 
      thelist.append([city,x]) 

with open('Sorted.txt','w') as g: 
    for item in thelist: 
     string = item[0], ', '.join(map(str, item[1:])) 
     print string 

EDIT: Lesen Sie Kommentar unten für einige Hintergrundinformationen darüber, warum das passiert ist. Meine schnelle Lösung war:

if population: 
     x = population[0] 
     thelist.append([city,x]) 
+3

Die Regex wird nicht immer übereinstimmen und eine leere Liste zurück manchmal – JBernardo

+0

, dass Fragment Lauf unabhängig von der Python-Shell gibt an, dass es funktioniert. Die gleiche Eingabedatei wird ebenfalls verwendet. – Louis93

+1

offensichtlich nicht für * alle * Zeilen. –

Antwort

11

re.findall wird eine leere Liste zurück, wenn es keine Spiele sind:

>>> re.findall(r'\w+ly', 'this does not work') 
[] 
3

re.findall können Sie eine leere Liste in dem Fall zurück, wo es keine Übereinstimmung war. Wenn Sie versuchen, auf [][0] zuzugreifen, sehen Sie, dass IndexError.

in Rechnung zu tragen, keine Streichhölzer, Sie etwas entlang der Linien von verwenden sollten:

match = re.findall(...) 
if match: 
    # potato potato 
1

Ich hatte das gleiche Problem. Die Lösung scheint sehr einfach zu sein, und ich weiß nicht, warum ich nicht darüber nachgedacht habe.

if match: 

statt

if match[0]: 
Verwandte Themen