2017-11-03 6 views
2

Ich habe gerade mit Python 2.7 für ein paar Monate gestartet. Ich arbeite normalerweise mit einer 2D-Liste in Python, einfache Aufgabe, aber ich frage mich, ob es eine elegantere Möglichkeit gibt, meinen Job in Python 2.7 zu erledigen?Elegante Art, mit 2D-Liste in Python zu arbeiten

Hier ist meine Aufgabe. Ich habe eine 2D-Liste:

Ich möchte die obige 2D-String-Liste in 2D Integer-Liste konvertieren.

expected_result = [[1, 2], [3, 4]] 

Wie üblich, kann ich wie folgt:

def convert_2D_string_list(my_list): 
    for a_group in my_list: 
     yield [int(k.replace("__cat_","")) for k in a_group] 

Aber die oben konnte nicht arbeiten, wenn meine Eingabe hat 3 Dimensionen wie:

my_second_list = [[["__cat_1", "__cat_2"], "__cat_12"], 
        [["__cat_3", "__cat_4"], "__cat_34"]] 

Wenn meine Eingangsliste integer ist Ich kenne den eleganten Weg um ihn zu transformieren. Zum Beispiel:

def convert_2D_int_list: 
    my_list = [[1, 2], [3, 4]] 
    import numpy as np 
    # Assume that, I want to add 1 for each of element 

    # Convert to numpy array 
    my_list = np.asarray(my_list) 
    my_list += 1 

    # my_list = [[2, 3], [4, 5]] 
    return my_list 

Was ist die beste Methode für meine convert_2D_string_list Methode? Also im Falle ist es nicht 2D-Liste, aber 3D-Liste -> Ich habe keine Angst vor der Anzahl der Dimensionen.

Jeder Vorschlag wäre willkommen. Danke.

+1

Die wichtige Sache zu verstehen ist, dass Listen haben keine Dimension ns. Außerdem würde ich nicht aufrufen, eine Liste in ein elegantes Array umzuwandeln, wenn das, was Sie wirklich wollen, eine Liste ist. Sie sind zwei verschiedene Datenstrukturen mit unterschiedlichen Anwendungsfällen. –

+0

Ich würde eine rekursive Funktion empfehlen. – norok2

+0

@ juanpa.arrivillaga Sie haben absolut recht. Meine Liste hat keine Dimensionen. Ich möchte nur eine will das Multi-Dimension-Array in die andere Form konvertieren, aber behalten Sie die Dimension. Vielleicht ist "elegant" hier nicht geeignet. Tut mir leid für mein schlechtes Englisch. –

Antwort

2

Numpy Array funktioniert sehr gut mit Zahlen, es ist ein wenig trickreicher mit Strings. np.vectorize ist eine Arbeit für eine solche Situation, auch keine Leistungsverbesserung ist getan. Aber es schafft viele Dimensionen, ich hoffe, Sie werden es elegant finden.

a=np.array([[[['__cat_0', '__cat_1'], 
     ['__cat_2', '__cat_3']], 

     [['__cat_4', '__cat_5'], 
     ['__cat_6', '__cat_7']]], 


     [[['__cat_8', '__cat_9'], 
     ['__cat_10', '__cat_11']], 

     [['__cat_12', '__cat_13'], 
     ['__cat_14', '__cat_15']]]]) 


def f(str): return int(str[6:])   
fv=np.vectorize(f) 

print(fv(a)) 

gibt:

[[[[ 0 1] 
    [ 2 3]] 

    [[ 4 5] 
    [ 6 7]]] 


[[[ 8 9] 
    [10 11]] 

    [[12 13] 
    [14 15]]]]  

Bemerkung: a ist np.vectorize(lambda n : '__cat_'+str(n))(np.arange(16).reshape((2,)*4));)

+0

Sorry, vielleicht "elegant" ist in diesem Fall nicht genau geeignet, aber es ist genau das, was ich will. Vielen Dank @B. M. –

+0

Ich kann benutzerdefinierte 'f' Funktion wie benötigt. Hinzufügen, Ersetzen, Strim, etc. Super! –

0

Sie Ihre Zeichenfolge 2D-Liste konvertieren 2D-Liste mit Karte und Listenkomprehensionen

my_list = [["__cat_1", "__cat_2"],["__cat_3", "__cat_4"]]  
my_list = [map(lambda z: int(z.split('_')[-1]), ls) for ls in my_list] 
print my_list # [[1,2],[3,4]] 

3d Liste int:

my_list = [["__cat_1", "__cat_2", '__cat_3'],["__cat_1", "__cat_2", '__cat_3']] 
my_list = [map(lambda z: int(z.split('_')[-1]), ls) for ls in my_list] 
print my_list # [[1,2,3],[1,2,3],[1,2,3]] 
+0

Ja. Es kann ein anderer Ansatz sein, aber nicht definitiv, was ich will. I Fall von 'my_list' könnte 3-dimensionale Liste sein. Es kann nicht funktionieren. Deshalb denke ich, dass es nicht elegant ist. –

+0

sogar drei Dimension Liste funktioniert, können Sie versuchen, dass –

+1

Sorry, aber es ist nicht 3D. Es ist immer noch 2D-Liste. Bitte schau dir meine Frage an, ich habe gerade ein Beispiel mit 3D-Liste aktualisiert. –

0

Ich hoffe, dies kann nützlich für Sie:

def con(x): # you can do here whatever u want return x.split('_')[-1] y= [con(v) for v in my_list]

2

die Werte ändern, während rekursiv die Liste kopiert (s).

def visit(fn, xs): 
    return [visit(fn, x) if isinstance(x, list) else fn(x) for x in xs] 

in diesem Fall ist die Änderungsfunktion fn ist so etwas wie:

def categorize(s): 
     return int(re.match(r'__cat_(\d*)', s).group(1)) 

diese Prüfung:

my_second_list = [[["__cat_1", "__cat_2"], "__cat_12"], 
       [["__cat_3", "__cat_4"], "__cat_34"]] 

print visit(categorize, my_second_list) 

Ausgänge:

> [[[1, 2], 12], [[3, 4], 34]] 
Verwandte Themen