Seite 1 von 1
`map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Donnerstag 30. Mai 2019, 20:35
von Atalanttore
Hallo
Die Koordinaten (x, y, z) in einem `set()` mit Tupeln würde ich gerne mit der `map`-Funktion abändern. Auf jede Achse soll eine andere Funktion angewendet werden.
Bei meinem unten erstellten Beispielcode kommt folgende Fehlermeldung:
Code: Alles auswählen
Traceback (most recent call last):
File "/home/ata/source/move-coordinates.py", line 20, in <module>
result_x = map(add_30, i[0])
TypeError: 'int' object is not iterable
Was habe ich falsch gemacht?
Code:
Code: Alles auswählen
coordinates = {(34, 45, 435), (78, 67, 76), (45, 35, 98), (56, 86, 68), (32, 46, 86)}
results = set()
def add_30(n):
return n + 30
def add_20(n):
return n + 20
def add_10(n):
return n + 10
for i in coordinates:
result_x = map(add_30, i[0])
result_y = map(add_20, i[1])
result_z = map(add_10, i[2])
results.add((result_x, result_y, result_z))
print(results)
Gruß
Atalanttore
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Donnerstag 30. Mai 2019, 20:50
von sparrow
Warum nutzt du keine list comprehension?
Oder übersehe ich hier etwas beim erwarteten Resultat?
Code: Alles auswählen
>>> coordinates
{(32, 46, 86), (45, 35, 98), (56, 86, 68), (78, 67, 76), (34, 45, 435)}
>>> [(e[0]+30, e[1]+20, e[2]+10) for e in coordinates]
[(62, 66, 96), (75, 55, 108), (86, 106, 78), (108, 87, 86), (64, 65, 445)]
>>>
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Donnerstag 30. Mai 2019, 20:54
von snafu
Du hast anscheinend
map() noch nicht richtig verstanden. Du iterierst bei deinem Beispiel über alle Tupel und nimmst davon via
i[0] das jeweils erste Element. Dies ist eine Zahl und damit kann
map() nichts anfangen, weil es etwas iterierbares erwartet, z.B. eine Liste oder ein Tupel. Aber selbst wenn du nur
i übergeben würdest, käme nicht heraus, was du erwartest. Du suchst wohl eher etwas in dieser Art:
Code: Alles auswählen
print([(x + 10, y + 20, z + 30) for x, y, z in coordinates])
Oder eben direkt als Set:
Code: Alles auswählen
set((x + 10, y + 20, z + 30) for x, y, z in coordinates)
Man kann in Python, wie du siehst, die Schleife zum Transformieren der Daten und die Erzeugung des neuen Containers unmittelbar als Einzeiler verknüpfen.
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Donnerstag 30. Mai 2019, 21:32
von snafu
@Atalanttore: Wenn du viel mit Zahlen und Berechnungen machst, dann schau dir auch mal die wissenschaftlichen Pakete für Python an, die man zusätzlich installieren kann. Ein populäres davon ist
pandas. Das kann Daten auch aus externen Quellen, z.B. einer CSV-Datei, beziehen. Zum Verändern der Koordinaten kann man dann sogar die Schleife weglassen:
Code: Alles auswählen
In [11]: df = pd.DataFrame({(34, 45, 435), (78, 67, 76), (45, 35, 98), (56, 86, 68), (32, 46, 86)})
In [12]: df
Out[12]:
0 1 2
0 32 46 86
1 45 35 98
2 56 86 68
3 78 67 76
4 34 45 435
In [13]: df + (10, 20, 30)
Out[13]:
0 1 2
0 42 66 116
1 55 55 128
2 66 106 98
3 88 87 106
4 44 65 465
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Donnerstag 30. Mai 2019, 23:18
von __blackjack__
Ich würde hier auch eine comprehension schreiben, es sei denn man hat bereits eine passende Funktion die man anwenden kann. Nur um das mit `map()` mal gesehen zu haben:
Code: Alles auswählen
In [7]: set(map(lambda p: (p[0] + 30, p[1] + 20, p[2] + 10), coordinates))
Out[7]: {(62, 66, 96), (64, 65, 445), (75, 55, 108), (86, 106, 78), (108, 87, 86)}
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Freitag 31. Mai 2019, 19:49
von Atalanttore
sparrow hat geschrieben: Donnerstag 30. Mai 2019, 20:50
Warum nutzt du keine list comprehension?
Oder übersehe ich hier etwas beim erwarteten Resultat?
snafu hat geschrieben: Donnerstag 30. Mai 2019, 20:54
Du iterierst bei deinem Beispiel über alle Tupel und nimmst davon via
i[0] das jeweils erste Element. Dies ist eine Zahl und damit kann
map() nichts anfangen, weil es etwas iterierbares erwartet, z.B. eine Liste oder ein Tupel. Aber selbst wenn du nur
i übergeben würdest, käme nicht heraus, was du erwartest. Du suchst wohl eher etwas in dieser Art:
Code: Alles auswählen
print([(x + 10, y + 20, z + 30) for x, y, z in coordinates])
Oder eben direkt als Set:
Code: Alles auswählen
set((x + 10, y + 20, z + 30) for x, y, z in coordinates)
Man kann in Python, wie du siehst, die Schleife zum Transformieren der Daten und die Erzeugung des neuen Containers unmittelbar als Einzeiler verknüpfen.
__blackjack__ hat geschrieben: Donnerstag 30. Mai 2019, 23:18
Ich würde hier auch eine comprehension schreiben, es sei denn man hat bereits eine passende Funktion die man anwenden kann. Nur um das mit `map()` mal gesehen zu haben:
Code: Alles auswählen
In [7]: set(map(lambda p: (p[0] + 30, p[1] + 20, p[2] + 10), coordinates))
Out[7]: {(62, 66, 96), (64, 65, 445), (75, 55, 108), (86, 106, 78), (108, 87, 86)}
Danke für die vielen Erläuterungen. Eine Comprehension führt zum gewünschten Ergebnis. Die Variante mit `map()` und `lambda`-Funktion sieht auch komplizierter aus.
`map()` habe ich noch nie gebraucht. Ist `map()` nur für die Anwendung von längeren Funktionen, die für eine Comprehension zu lange sind, gedacht?
snafu hat geschrieben: Donnerstag 30. Mai 2019, 20:54
Du hast anscheinend
map() noch nicht richtig verstanden.
Ich vermute, dass ich vieles an Python noch gar nicht kenne.
snafu hat geschrieben: Donnerstag 30. Mai 2019, 21:32
@Atalanttore: Wenn du viel mit Zahlen und Berechnungen machst, dann schau dir auch mal die wissenschaftlichen Pakete für Python an, die man zusätzlich installieren kann. Ein populäres davon ist
pandas. Das kann Daten auch aus externen Quellen, z.B. einer CSV-Datei, beziehen. Zum Verändern der Koordinaten kann man dann sogar die Schleife weglassen:
Code: Alles auswählen
In [11]: df = pd.DataFrame({(34, 45, 435), (78, 67, 76), (45, 35, 98), (56, 86, 68), (32, 46, 86)})
Danke für den Hinweis.
Gruß
Atalanttore
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Freitag 31. Mai 2019, 23:13
von __blackjack__
@Atalanttore: `map()` ist ein typisches funktionales Werkzeug. Die Funktion ist praktisch wenn man ein „iterable“ und eine Funktion/Methode hat, und die auf jedes Element anwenden will und ein damit ein neues „iterable“ mit den Ergebnissen bekommt. Beispiele wäre das parsen einer Zeile mit Koordinaten: ``x, y, z = map(int, line.split(','))``. Oder wenn man eine Liste mit Objekten hat, deren Zeichenkettenrepresentation man durch ein Zeichen getrennt dargestellt haben möchte: ``', '.join(map(str, items))``.
Re: `map`-Funktion auf `set()` mit Tupeln anwenden
Verfasst: Samstag 1. Juni 2019, 13:38
von Atalanttore
@__blackjack__: Danke für die Erklärung.
Gruß
Atalanttore