2016-03-28 3 views
2

Angenommen ich die folgende zweidimensionale Anordnung haben:Wie erhalten Sie String-Werte von zweidimensionalen Array und zuweisen zu einem eindimensionalen Array?

m_array = [['String A', 1, 1.1, 'haha'], 
      ['String B', 2, 0.9, 'haha'], 
      ['String C', 0, 1.1, 'haha'], 
      ['String D', 3, 0.9, 'haha']] 

zu tun: ich die 0-Indexwerte für dieses Multi-Array extrahieren erhalten möchten, das ist die 'String A', ‚String B ',' String C ',' String C 'und speichern Sie es in einem einzigen Array: s_array dynamisch.

Problem: Ich verwende eine for-Schleife, um alle Werte zu durchlaufen. Hier ist der Code

# create a single dimensional array 
    s_array = [] 
    # Iterator is the length of the m_array. (Which should be 4; 0-index, 1-index, 2-index and 3-index  
    iterator = range(len(m_array)) 

    i_array = 0 

    if(i_array <=iterator): 
     for str_value in m_array[i_array][0]: 
      s_array.append(str_value) 

An diesem Punkt s_array ist haben:

s_array['String A', 'String B', 'String C', 'String D']

aber es funktioniert nicht.

Ich denke, etwas stimmt nicht mit der Logik meines Codes. Aber ich kann das Problem nicht erkennen, irgendwelche Ideen?

+0

Was erwarten Sie? If (i_array <= iterator): 'tun? –

Antwort

2

eine Liste Verständnis Verwendung:

s_array = [sublist[0] for sublist in m_array] 
print s_array 
>>> ['String A', 'String B', 'String C', 'String D'] 
1

Du statt anhängt die gesamte Liste in m_array[i_array][0] und Anhängen jedes Element durch jedes Element iteriert. Sie müssen keine Indizierung verwenden, obwohl, weil man nur durch m_array laufen kann:

s_array = [] 
for array in m_array: 
    s_array.append(array[0]) 

Wenn alle eine for Schleife ist, die Dinge auf eine Liste hinzufügt, das ist ein Zeichen dafür, dass Sie wahrscheinlich eine list comprehension verwenden können :

s_array = [array[0] for array in m_array] 
2

Eine sehr kompakte Art und Weise, dies zu tun, ist die eingebaute in zip Funktion zu verwenden. Angesichts

m_array = [['String A', 1, 1.1, 'haha'], 
      ['String B', 2, 0.9, 'haha'], 
      ['String C', 0, 1.1, 'haha'], 
      ['String D', 3, 0.9, 'haha']] 

dann

zip(*m_array) 

kehrt

[('String A', 'String B', 'String C', 'String D'), (1, 2, 0, 3), (1.1000000000000001, 0.90000000000000002, 1.1000000000000001, 0.90000000000000002), ('haha', 'haha', 'haha', 'haha')] 

Das ist, weil die * "Klecks" Operator die Elemente in m_array auspackt und übergibt jedes als Argument an zip. Siehe Unpacking Argument Lists im offiziellen Python-Lernprogramm.

Also müssen wir nur das erste Tupel extrahieren und es in eine Liste konvertieren.

s_array = list(zip(*m_array)[0]) 
print(s_array) 

Ausgang

['String A', 'String B', 'String C', 'String D'] 
+0

Basis Python, das ist der beste Ansatz! –

+1

@ColonBeauvel .. Warum sagst du, es ist der beste Ansatz? ... Was ist mit Listenverständnis? –

+0

@ColonelBeauvel: Danke! Ich schätze, es verschwendet ein wenig mehr RAM als BAHs List Comp; OTOH, es ist (wahrscheinlich) schneller, besonders wenn die Unterlisten lang sind, da 'zip's Schleifen bei C-Geschwindigkeit statt der Python-Geschwindigkeit einer Listenkomp 'für'-Schleife passiert. –

0

Wie Sie viele Möglichkeiten, es zu sehen. Das Beste von allem für die aktuelle Situation, denke ich, ist list comprehension.

Ein interessanter Weg ist, zu verwenden map und itemgetter:

m_array = [['String A', 1, 1.1, 'haha'], 
      ['String B', 2, 0.9, 'haha'], 
      ['String C', 0, 1.1, 'haha'], 
      ['String D', 3, 0.9, 'haha']] 

from operator import itemgetter 

print(list(map(itemgetter(0), m_array))) 
+1

FWIW, ich vermute, dass das OP mit Python 2 (sonst sie bekomme einen Fehler beim Vergleich eines 'int' mit einem' range' Objekt. Und in Python 2 kann der 'list' Aufruf entfallen, da Python 2' map' eine 'list' anstelle eines Iterators zurückgibt. –

0

Ich denke, das Problem zu sehen. Sie durchlaufen "String A" anstelle von m_array. m_array [i_array] [0] ist "String A" und Sie ändern den Wert von i_array nicht.

Einfach fix:

for sublist in m_array: 
    s_array.append(sublist[0]) 

Es tut mir leid, wenn dies nicht hilft, aber ich kann nicht zur Klärung fragen, was versuchen Sie (nicht genug Ruf) zu erreichen.

0

Im Anschluss an die Kommentare zu PM 2RING ‚s Antwort, ich habe einige Profilierungs Tests, die die folgenden Ergebnisse ergab:

>>> import timeit 
>>> timeit.timeit('[x[0] for x in m_array]', "m_array = [['String A', 1, 1.1, 'haha'], ['String B', 2, 0.9, 'haha'],['String C', 0, 1.1, 'haha'],['String D', 3, 0.9, 'haha']]",number = 10**6) 
0.3232365940002637 
>>> timeit.timeit('list(zip(*m_array))[0]', "m_array = [['String A', 1, 1.1, 'haha'], ['String B', 2, 0.9, 'haha'],['String C', 0, 1.1, 'haha'],['String D', 3, 0.9, 'haha']]",number = 10**6) 
0.6186811590014258 

Hinweis: -Test durchgeführt, auf meinem Ubuntu 14.04 Box, LENOVO THINKPAD Ultrabook mit Core i7.