2016-11-08 2 views
4

ich einen neuen Programmierer Lernt Python bin und Probleme habe mit dieser Aufgabe zu nähern:Aufeinander folgende Zugabe von Zahlen in einem String

So im Wesentlichen habe ich eine Reihe von Zahlen aus einer Datei importiert zu lesen, und Notwendigkeit um die Summe der ersten Zahl zu der zweiten hinzuzufügen und sie in das korrekte ASCII-Zeichen umzuwandeln. So zum Beispiel, wenn ich die Zeichenfolge lese:

'36 30 25 40 80 4' 

Ich möchte 36-30 hinzuzufügen, dann 25 bis 40, dann 80-4 und so weiter, bevor sie an den entsprechenden ASCII-Zeichen und Druck Umwandlung (also in diesem Fall "CAT").

Bisher erkenne ich, dass ich einen Split-Befehl verwenden muss, um die Zeichenfolge aufzuteilen, und dann eine For-Schleife, um die Daten für fortlaufende Nummern zu nehmen. Ich kann den korrekten Wert für den ersten Buchstaben erhalten, habe aber Probleme, dem Programm zu sagen, dass es automatisch weitermachen soll, um [2] zu [3] hinzuzufügen, nachdem [1] zu [0] hinzugefügt wurde. Ich muss das auch für mehrere Zeilen tun.

Wieder bin ich ein neuer Programmierer, so dass jede Hilfe sehr geschätzt wird. Vielen Dank!

+2

Bekommst du Katzen und Fledermäuse durcheinander? – wim

Antwort

2

Eine andere Methode, die weniger undurchsichtig ist (obwohl ausführlicher) als würde Patrick Vorschlag sein:

>>> x = '36 30 25 40 80 4' 
>>> nums = [int(n) for n in x.split()] 
>>> ''.join(chr(sum(nums[i:i+2])) for i in range(0, len(nums), 2)) 
'BAT' 
+0

Das war eigentlich viel einfacher zu verstehen als Patrick's, da ich Karten- und Zip-Funktionen noch nicht gelernt habe. Vielen Dank! – chillbro

+0

@chillbro bei jsbuenos suggestion, ich habe in einem kurzen Überblick über das, was in meinem Beispiel vorgeht, editiert, damit ich hoffe das hilft dir zu verstehen was ich da mache. Ich hoffe, es hilft. –

0

Sie können es tun, indem Liste comprehesnion als:

>>> my_string = '36 30 25 40 80 4' 
>>> num_list = [int(num) for num in my_string.split()] # list of numbers 
>>> ''.join(chr(sum(c_num)) for c_num in zip(num_list[:-1:2], num_list[1::2])) 
'BAT'  #         ^iterate simultaneous value with step 2 
+0

Nicht ganz, was gefragt wurde ... – lucasnadalutti

+0

Das ist nicht das, was das OP fragte – coder

0

Sie für Schleife mit Bereich mit Schritt 2

for i in range(0, 6, 2): 
     do something to el[i] and el[i+1] 

Auf diese Weise können Sie das Programm sagen kann zu gewünschten Index gehen . Hier i in Schleife Werte erhalten: [0, 2, 4]

3

Sie eine besondere Verwendung von zip verwenden können, um Elemente zu paaren:

s = '36 30 25 40 80 4' 
ints = map(int, s.split()) #make into list of ints 
sums = map(sum, zip(*[iter(ints)]*2)) 
print(''.join([chr(i) for i in sums])) 

Edit: technisch iter ist hier nicht notwendig, aber ich schreibe es, weil ich manchmal vergesse, wenn ich es brauche.

Edit 2: Adressieren jsbuenos Punkte unter:

map nimmt eine Funktion und eine iterable (wie eine Liste) und wendet die Funktion auf jedes Element dieser iterable. So ist list(map(int, ['1', '2'])) das gleiche wie [int('1'), int('2')]. Die list ist da, weil map tatsächlich einen Iterator zurückgibt, der die Werte einzeln statt alle auf einmal erzeugt.

Die Verwendung von zip hier sieht komplex aus, aber das ist meistens die ganze Interpunktion. Lass uns versuchen, es zu durchbrechen. Wie ich bereits erwähnt habe, brauchen wir das iter hier nicht, weil ints ein map Objekt ist und somit bereits ein Iterator, also müssen wir keinen Iterator dafür machen. So, jetzt sieht es aus wie

sums = map(sum, zip(*[ints]*2)) 

Alle map tut besteht die Paare Zugabe, nachdem wir sie paaren, so lassen wir das verwerfen.

zip(*[ints]*2) 

Der Trick, um das Verständnis dieser diese Liste Multiplikation ist das Verständnis geschieht zuerst

zip(*[ints, ints]) 

Die * vor einem iterable das Auspacken Operator ist. Betrachten Sie es als die Liste ihre Argumente in die Funktion Dumping

zip(ints, ints) 

Also, was ist zip tatsächlich tun? Die normale Verwendung von zip besteht darin, zwei Iterables zu nehmen und die Elemente wie oben zu paaren.

list(zip([1,2,3], [4,5,6])) #put the results from zip into a list 
[(1, 4), (2, 5), (3, 6)] 

Es funktioniert mit mehr als zwei Listen auch, aber dafür sind wir nicht hier.

Es ist wichtig zu beachten, dass in zip(ints, ints) die beiden ints Argumente das gleiche Objekt sind. Das bedeutet, wenn zip das erste Paar erstellt, erhält es zuerst das nächste Element vom ersten Argument ints. Das ist 36. Dann erhält es das nächste Element von seinem zweiten Argument, das dasselbe ints ist. Also das nächste Element ist 30. Es liefert dann diese zwei Elemente in einem Tupel und fährt fort, den Prozess für den Rest des Iterators zu wiederholen. Wenn Sie sich fragen, warum zip(*[iter(ints)]*2) schreiben, wenn zip(ints, ints) dasselbe bedeutet? Das liegt daran, dass Sie sicherstellen müssen, dass die Argumente das gleiche Objekt sind oder dass es nicht funktioniert. Doing zip(iter(ints),iter(ints)) würde nicht funktionieren, weil jeder iter einen anderen, wenn auch identischen, Iterator zurückgibt. Ich habe Probleme, mich zu erinnern, wenn ich iter verwenden muss, um auf Nummer sicher zu gehen, verwende ich es einfach die ganze Zeit.

+3

"Technisch" Ich habe ernsthafte Zweifel, ob Sie tatsächlich einem selbsternannten "neuen Programmierer" mit einer solchen Syntax helfen, ohne sich zu erklären. – jsbueno

+0

@jsbueno Sorry, ich folge nicht ganz. Willst du damit sagen, dass ich den Disclaimer entfernen sollte, dass ich den iter entfernen sollte, oder dass ich erklären sollte, was 'iter' hier macht? –

+2

Ich sage, dass Sie ein weiteres Beispiel hinzufügen sollten, mit einem einfachen, mlultiline 'for' obendrein, schreiben Sie in einfachem Englisch, was vor sich geht, und behalten Sie Ihr aktuelles Beispiel und erklären Sie int in einfachem Englisch - sonst diese Antwort ist nur gut als Code Golf für sich selbst, nicht für die OP - wer wird nicht verstehen, keine von 'map',' zip' und das Verständnis am Ende. – jsbueno

0

Eine andere Lösung:

string = '36 30 25 40 80 4' 
numbers = [int(e) for e in string.split()] 
res = ''.join([chr(numbers[i]+numbers[i+1]) for i in range(0,len(numbers),2)]) 
print(res) 

Ausgang: BAT

1

Sie kann es mit einem Klacks wie folgt tun:

In [18]: str='36 30 25 40 80 4' 

In [19]: nums=str.split() 

In [20]: for i in range(0, len(nums), 2): 
    print(int(nums[i]) + int(nums[i+1])) 
    ....:  
66 
65 
84 

Möglicherweise möchten Sie überprüfen, dass die len (nums) gerade ist. Wenn nicht, wird ein IndexError geworfen.

2

Wenn dies ascii Codierung ist, denke ich, dass Sie tatsächlich "BAT" statt "CAT" haben.

>>> s = '36 30 25 40 80 4' 
>>> ints = [int(n) for n in s.split()]    # convert strings to integers 
>>> summed = [x+y for x,y in zip(ints[0::2], ints[1::2])]  # summing pairs 
>>> bytearray(summed).decode('ascii')     # decoding to ascii text 
'BAT' 
+2

'Bytearray (summiert) .decode ('ASCII')' etwas aus der Box, +1 –

0

Eine kleine Änderung von Patricks Antwort.

>>> t = "36 30 25 40 80 4" 
>>> t_s = map(int,t.split()) 
>>> t_s 
[36, 30, 25, 40, 80, 4] 
>>> "".join([chr(sum(c)) for c in zip(t_s[1::2],t_s[::2])]) 
'BAT' 
0

können Sie erweiterte Liste Slicing verwenden Paare benachbarter Zahlen zu erhalten:

s = '36 30 25 40 80 4' 
a = [int(x) for x in s.split()] #convert to integers 
firsthalf = a[::2] #every other starting from 0 
secondhalf = a[1::2] #every other starting from 1 

Dann können Sie zip verwenden, um die Hälften zu paaren werden aufsummiert:

pairs = zip(firsthalf, secondhalf) 

dann können Sie Karte sum auf jedem Teil von Paris:

ordinals = [sum(x) for x in pairs] 

um schließlich in eine Zeichenfolge zu konvertieren, rufen:

print(''.join([chr(x) for x in ordinals])) #prints: 'BAT' 
0

Viele Weg, dies zu tun, aber ohne eine Reihe von Zwischenlisten zu erstellen, können Sie einfach einen Iterator erstellen und einen Generator verwenden, um die Zeichenfolge zu erstellen:

>>> s = '36 30 25 40 80 4' 
>>> i = iter(map(int, s.split())) 
>>> ''.join(chr(sum(x)) for x in zip(i, i)) 
'BAT' 
0

Sie die Zeichenfolge in die Iterator umwandeln kann ints, und verwenden Sie next Funktion in einer Liste Verständnis Rückkehr:

s = '36 30 25 40 80 4' 

# iter is not necessary in python3 
itr = iter(map(int, s.split())) 
word = ''.join(chr(a+next(itr)) for a in itr) 

print(word) 
# BAT 

IMO das ist ein bisschen sauberer, weil es keine explizite Indizierung gibt.

Verwandte Themen