2015-06-23 24 views
6

Mam listę tysięcy elementów formy tak:Jak mogę ocenić listę ciągów jako listę krotek w Pythonie?

pixels = ['(112, 37, 137, 255)', '(129, 39, 145, 255)', '(125, 036, 138, 255)' ...] 

Próbuję przekonwertować te elementy ciągów do krotek korzystających ast.literal_eval, ale łamie po napotkaniu rzeczy jak wiodącymi zerami (np pokazany trzeci łańcuch) z błędem SyntaxError: invalid token.

pixels = [ast.literal_eval(pixel) for pixel in pixels] 

Jaki byłby dobry sposób na radzenie sobie z takimi rzeczami i uzyskanie listy list ocenianych jako lista krotek?

+0

@BhargavRao Cyfry ósemkowe w Pythonie 3 nie obsługują formatu 0xx. –

+0

@BhargavRao Witaj. Określony błąd to '' SyntaxError: invalid token''''. Właśnie dodałem to pytanie. – d3pd

+2

@BhargavRao Wiodące '0' w Pythonie 2.x było ósemkowym dosłownym. W Pythonie 3.x nie jest to już dozwolone. Na przykład '055' jest liczbą ósemkową dla wartości dziesiętnej" 45 ". – CoryKramer

Odpowiedz

4

Użyj modułu re.

>>> import re 
>>> import ast 
>>> pixels = ['(112, 37, 137, 255)', '(129, 39, 145, 255)', '(125, 036, 138, 255)'] 
>>> [ast.literal_eval(re.sub(r'\b0+', '', pixel)) for pixel in pixels] 
[(112, 37, 137, 255), (129, 39, 145, 255), (125, 36, 138, 255)] 

re.sub(r'\b0+', '', pixel) pomaga usunąć zera. \b dopasowania pomiędzy znakiem słownym i nie-słownym lub odwrotnie, więc tutaj musi istnieć granica słowa istniejąca przed zerem i po spacji lub symbolem (.

Aktualizacja:

>>> pixels = ['(0, 0, 0, 255)', '(129, 39, 145, 255)', '(125, 036, 138, 255)'] 
>>> [ast.literal_eval(re.sub(r'\b0+\B', '', pixel)) for pixel in pixels] 
[(0, 0, 0, 255), (129, 39, 145, 255), (125, 36, 138, 255)] 
+0

Dziękuję bardzo za pomoc w tej sprawie. Twoje rozwiązanie jest bardzo bliskie, ale zrywa zerowe elementy krotek, na przykład '' '(0, 0, 0, 255)' '' zostaje ocenione na '' '(,,,, 255)' ''. Czy zdarzyłoby Ci się to obejść? – d3pd

+0

Goood catch, spróbuj '[ast.literal_eval (re.sub (r '\ b0 + \ B', '', pixel)) dla pikseli w pikselach]' –

+0

Alternatywne podejście do regex: '[tuple (int (d) for d w re.findall ('\ d +', pixel)) dla pikseli w pikselach] '. (Nie tak dobry jak wysłana odpowiedź.) –

4

Nie ma potrzeby korzystania ast.literal_eval lub re. Po prostu usuń nawiasy i przekonaj do liczb całkowitych:

def tupleize(s): 
    s = s.strip('()').split(',') 
    return tuple(int(entry) for entry in s) 

pixels = [tupleize(pixel) for pixel in pixels] 
+0

Dziękuję bardzo za rozwiązanie. To także dobre podejście. – d3pd