Nach Reihenfolge replacen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MupfSpace
User
Beiträge: 169
Registriert: Montag 25. Dezember 2017, 20:26

Samstag 12. Dezember 2020, 16:54

Hallo,

angenommen ich habe einen String: "##########"
und eine Liste: [".", ","].

Jetzt möchte ich alle "#" durch die Elemente in der Liste ersetzen, allerdings dings nicht nur mit einem der beiden oder in einer zufälligen Reihenfolge sonder in der Reinfolge, wie sie in der Liste sind, also in diesem Fall: ".,.,.,.,.,"

Wie mache ich das?

string.replace(liste) funktioniert nicht (ist aber eigentlich auch klar)
Benutzeravatar
pillmuncher
User
Beiträge: 1268
Registriert: Samstag 21. März 2009, 22:59
Wohnort: München

Samstag 12. Dezember 2020, 17:09

Das hier könnte hilfreich sein: https://docs.python.org/3/library/itert ... ools.cycle

Außerdem musst du vermutlich den String in einer for-Schleife zeichenweise durchgehen und einen neuen String Schritt für Schritt selbst erzeugen.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
__blackjack__
User
Beiträge: 8881
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Samstag 12. Dezember 2020, 18:29

Kommen da auch andere Zeichen als "#" in der ursprünglichen Zeichenfolge vor?
Q: What is the volume of a pizza of radius z and thickness a?
A: pi·z·z·a
MupfSpace
User
Beiträge: 169
Registriert: Montag 25. Dezember 2017, 20:26

Samstag 12. Dezember 2020, 18:46

__blackjack__ hat geschrieben:
Samstag 12. Dezember 2020, 18:29
Kommen da auch andere Zeichen als "#" in der ursprünglichen Zeichenfolge vor?
Jain,
es kommen neben # noch lehrzeichen und \n vor, aber die sollen nicht replaced werden. Aber sonst nur #
Benutzeravatar
python-neophyte
User
Beiträge: 5
Registriert: Donnerstag 10. Dezember 2020, 14:40

Samstag 12. Dezember 2020, 20:14

1. Technisch gesehen kannst du keine Zeichen im String "ersetzen", String ist ein unveränderlicher Datentyp. Du kannst nur einen neuen String erzeugen (in Python 3.x)

2. Wenn der String und die Liste die gleiche Länge hätten, hättest du die Funktion zip() verwenden können. Da sie das aber nicht sind, hier ein Schnipsel, der funktioniert.

Code: Alles auswählen

a = ['.', ';']
b = "odalksdjalkdj"
c = ""
for i in range(len(b)):
	c += a[i % len(a)]
print(c)
>> '.;.;.;.;.;.;.'

Der Winter ist eine Sommerpause.
Benutzeravatar
__blackjack__
User
Beiträge: 8881
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Samstag 12. Dezember 2020, 22:43

@python-neophyte: Ich sehe nicht wie das eine Lösung sein sollte, denn da sind ja nicht mal "#"-Zeichen in `b`. Und das was da ineffizient mit einer Schleife gemacht wird, könnte man auch in einem Ausdruck haben:

Code: Alles auswählen

In [298]: a                                                                     
Out[298]: ['.', ';']

In [299]: b                                                                     
Out[299]: 'odalksdjalkdj'

In [300]: ("".join(a) * ((len(b) + 1) // 2))[: len(b)]                          
Out[300]: '.;.;.;.;.;.;.'
Man könnte das `re`-Modul zum suchen und ersetzen verwenden:

Code: Alles auswählen

In [301]: b = "## ### # #####\n"                                                

In [302]: import re                                                             

In [303]: from itertools import cycle                                           

In [304]: from functools import partial                                         

In [305]: re.sub("#", partial(next, cycle(a)), b)                               
Out[305]: '.; .;. ; .;.;.\n'
Q: What is the volume of a pizza of radius z and thickness a?
A: pi·z·z·a
Benutzeravatar
python-neophyte
User
Beiträge: 5
Registriert: Donnerstag 10. Dezember 2020, 14:40

Montag 14. Dezember 2020, 12:36

__blackjack__ hat geschrieben:
Samstag 12. Dezember 2020, 22:43
@python-neophyte: Ich sehe nicht wie das eine Lösung sein sollte, denn da sind ja nicht mal "#"-Zeichen in `b`. Und das was da ineffizient mit einer Schleife gemacht wird, könnte man auch in einem Ausdruck haben:

Code: Alles auswählen

In [298]: a                                                                     
Out[298]: ['.', ';']

In [299]: b                                                                     
Out[299]: 'odalksdjalkdj'

In [300]: ("".join(a) * ((len(b) + 1) // 2))[: len(b)]                          
Out[300]: '.;.;.;.;.;.;.'
Man könnte das `re`-Modul zum suchen und ersetzen verwenden:

Code: Alles auswählen

In [301]: b = "## ### # #####\n"                                                

In [302]: import re                                                             

In [303]: from itertools import cycle                                           

In [304]: from functools import partial                                         

In [305]: re.sub("#", partial(next, cycle(a)), b)                               
Out[305]: '.; .;. ; .;.;.\n'

Dies ist eindeutig eine Art Schulungsfrage für Anfänger. Meine Lösung ist leicht lesbar und erreicht das Ergebnis auf eine klare Art und Weise.

Wenn es zusätzliche Einschränkungen zur ursprünglichen Frage gäbe, z.B. "mach das mit 'list comprehension'" oder "mach das mit functools package", wäre das sinnvoll.

Ich denke nicht, dass es notwendig ist, fortgeschrittenere Techniken für die Lösung dieser einfachen Aufgaben zu verwenden, wenn es nicht explizit gefordert ist.
Der Winter ist eine Sommerpause.
Benutzeravatar
__blackjack__
User
Beiträge: 8881
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Montag 14. Dezember 2020, 12:52

@python-neophyte: Deine Lösung ist keine Lösung, da sie das gestellte Problem nicht löst.

Wenn es um Verständlichkeit geht, würde ich meine Lösung noch wie folgt abändern, damit das nicht so ”magisch” ist, das `next()` das Match-Objekt ”verschluckt”:

Code: Alles auswählen

In [112]: a_cycled = cycle(a)                                                   

In [113]: re.sub("#", lambda match: next(a_cycled), b)                          
Out[113]: '.; .;. ; .;.;.\n'
Sich Teile davon jetzt irgendwie kleinteilig mit Indexerei nachzubasteln wird letztlich auch nicht leichter nachvollziehbar. Man braucht halt nur mehr Code, mehr Variablen, und kann mehr Fehler machen.
Q: What is the volume of a pizza of radius z and thickness a?
A: pi·z·z·a
Antworten