2017-05-28 2 views
1

Hier ist ein Stück Code von Allen Downey auf dem GitHub Denken Bayes Buchs:Was bedeutet zip (* res) in Python im folgenden Code?

def ReadData(filename='showcases.2011.csv'): 
    """Reads a CSV file of data. 
    Args: 
     filename: string filename 
    Returns: sequence of (price1 price2 bid1 bid2 diff1 diff2) tuples 
    """ 
    fp = open(filename) 
    reader = csv.reader(fp) 
    res = [] 

    for t in reader: 
     _heading = t[0] 
     data = t[1:] 
     try: 
      data = [int(x) for x in data] 
      # print heading, data[0], len(data) 
      res.append(data) 
     except ValueError: 
      pass 

    fp.close() 
    return zip(*res) 

Die gesamte Datei kann unter folgenden URL zu sehen: link on Github for this file. herauszufinden

Ich versuche, was zip tut (* res) bedeutet auf der letzten Zeile des Codes? Speziell:

  1. Was macht ein '*', wenn es als Präfix verwendet wird. und nächst
  2. Was bedeutet die Zip-Funktion (* alles) tut

Ich bin neu in Python, so kann ich sein offensichtlich etwas zu fragen. Ich sehe den Hinweis des Autors im Docstring der Funktion, dass er eine Folge von (price1 price2 ...) zurückgibt, aber für mich ist das weniger klar.

UPDATE: auf James Rettie des anwer Anknüpfend, hier ist das, was ich bekomme, wenn ich den Code, den er in Python zur Verfügung gestellt laufen 3.6:

In [51]: zip(['a', 'b', 'c'], [1, 2, 3]) 
Out[51]: <zip at 0x1118af848> 

Während in Python den gleichen Code ausgeführt wird, die Ergebnisse 2.7 ergibt, dass er zur Verfügung gestellt wie unten gezeigt:

In [2]: zip(['a', 'b', 'c'], [1, 2, 3]) 
Out[2]: [('a', 1), ('b', 2), ('c', 3)] 

Können Sie erklären warum? Der Unterschied ist Python 2.7 und Python 3.6 ist wichtig für mich, da ich Python 2.7 immer noch unterstützen muss, aber ich würde gerne zu 3.6 wechseln.

+0

Dank um mich auf diesen Link zu verweisen. Es beantwortet meine Fragen oben. – Bharat

+2

Für Python 3 verwenden Sie 'list (zip (* x))'. Das Gute daran ist, dass dies auch in Python 2 funktionieren wird, da das Anwenden von "Liste" auf eine Liste immer noch die gleiche Liste enthält. – ImportanceOfBeingErnest

+0

Schön! Das wird für mich funktionieren. Vielen Dank. – Bharat

Antwort

1

In Python ist * der Operator 'splat'. Es wird zum Entpacken einer Liste in Argumente verwendet. Zum Beispiel: foo(*[1, 2, 3]) ist das gleiche wie foo(1, 2, 3).

Die Funktion zip() nimmt n iterables und gibt y Tupel zurück, wobei y der kleinste der Länge aller bereitgestellten Iterables ist. Das y Th-Tuple enthält das yte Element aller bereitgestellten Iterables.

Zum Beispiel:

zip(['a', 'b', 'c'], [1, 2, 3]) 

nachgeben

('a', 1) ('b', 2) ('c', 3) 

Für eine verschachtelte Liste wie res im Beispiel Ihnen zur Verfügung gestellten, zip(*res) Aufruf wird so etwas tun:

res = [['a', 'b', 'c'], [1, 2, 3]] 
zip(*res) 
# this is the same as calling zip(['a', 'b', 'c'], [1, 2, 3]) 
('a', 1) 
('b', 2) 
('c', 3) 
1

zip(*res) transponiert eine Matrix (2-d Array/Liste). Die * operator ‚entpackt‘ eine iterable oder Zeilen einer Matrix und zip Verschachtelungen und Reiß die Zeilen spaltenweise:

> x = [('a', 'b', 'c'), (1, 2, 3)] 
> zip(*x) 
[('a', 1), ('b', 2), ('c', 3)] 

Man stelle sich die Matrix auf der Diagonalspiegelung.