Seite 1 von 1

bestimmte Werte mit Slicing

Verfasst: Samstag 14. November 2009, 13:21
von piwi133
Hallo,
ich habe eine Liste, in der ich jeden zweiten Wert mit 0 ersetzen möchte.

Code: Alles auswählen

a=[1,2,3,4,5,6]
a[1::2]=[0,0,0]
Klappt soweit.

Wie schaff ich es nun, dass ich das Ergebnisvon Zeile 2 in eine Variable b mittels einem Kommando speichere?

Code: Alles auswählen

a[::]=t
bedeutet ja, dass t die selbe Anzahl der zu ersetzenden Zeichen haben muss. Kann ich dies auch dynamisch angegen?

Grüße Stefan

Verfasst: Samstag 14. November 2009, 13:43
von hendrikS
Möglicherweise so:

Code: Alles auswählen

a[1::2]=[0]*(len(a)/2)

Verfasst: Samstag 14. November 2009, 13:47
von piwi133
wunderbar, danke!
und wie kann ich dies nun on Variable b mit einem Kommando speichern?

Verfasst: Samstag 14. November 2009, 13:54
von numerix
piwi133 hat geschrieben:wunderbar, danke!
und wie kann ich dies nun on Variable b mit einem Kommando speichern?
Was für ein "Kommando"?

Verfasst: Samstag 14. November 2009, 14:00
von piwi133
ich möchte mit einem einzigen Kommando das Resultat in Variable b speichern.
In etwa so

Code: Alles auswählen

b=a[1::2]=[0]*(len(a)/2)
Dies ergibt aber

Code: Alles auswählen

>>> b
[0, 0, 0]
anstatt

Code: Alles auswählen

>>> b
[1, 0, 3, 0, 5, 0]

Verfasst: Samstag 14. November 2009, 14:04
von hendrikS
piwi133 hat geschrieben:wunderbar, danke!
und wie kann ich dies nun on Variable b mit einem Kommando speichern?
Es hängt ein bißchen davon ab,was aus a werden soll. Soll es generell unverändert bleiben, oder unverändert nachdem die Nullen eingefügt wurden, oder is es völlig egal?

Verfasst: Samstag 14. November 2009, 14:15
von piwi133
a sollte unverändert bleiben

Verfasst: Samstag 14. November 2009, 14:32
von hendrikS
piwi133 hat geschrieben:a sollte unverändert bleiben
Dann geht die Lösung von oben nicht, da diese ja a verändert. Dann entweder eine Kopie von a anlegen (nicht b = a!!) und die Operation von oben auf b anwenden oder vielleicht in einer list comprehension b aus a erzeugen. Denk mal drüber nach.

Verfasst: Samstag 14. November 2009, 14:39
von hendrikS
hendrikS hat geschrieben:
piwi133 hat geschrieben:a sollte unverändert bleiben
Dann geht die Lösung von oben nicht, da diese ja a verändert. Dann entweder eine Kopie von a anlegen (nicht b = a!!) und die Operation von oben auf b anwenden oder vielleicht in einer list comprehension b aus a erzeugen. Denk mal drüber nach.
Edit: Hab selbst gerade mal über eine LC Lösung nachgedacht. So adhoc ist mar gar nichts eingefallen. Vielleicht ist der erste Weg hier der einfachste. Oder vielleicht hat jemand anderes einen besseren Vorschlag.

Verfasst: Samstag 14. November 2009, 14:53
von yipyip
Wenn es einfach nur darum geht, jedes 2. Element durch 0 zu ersetzen:

Code: Alles auswählen

In [59]: ls = [1, 2, 3, 4, 5, 6]

In [60]: ls2 = [0 if i & 1 else x for i, x in enumerate(ls)]

In [61]: ls2
Out[61]: [1, 0, 3, 0, 5, 0]
Was mir noch eingefallen (und etwas allgemeiner) ist:

Code: Alles auswählen

def slice_replace(ls, start, step, val):
  res = ls[::]
  x = slice(start, None, step)
  res[x] = len(res[x]) * [val]
  return res

ls = [1, 2, 3, 4, 5, 6]

print slice_replace(ls, 1, 2, 0)
print ls
Vielleicht(?) etwas schoener:

Code: Alles auswählen

from itertools import cycle, izip

def list_replace(ls, start, step, val):
  return ls[:start] + \
         [x if i else val for i, x in izip(cycle(xrange(step)), ls[start:])]

print list_replace(ls, 1, 2, 0)
print ls
:wink:
yipyip

Verfasst: Samstag 14. November 2009, 15:49
von jerch
Sollte für dein Problem die Geschwindigkeit relevant sein, hier mal ein paar Ergebnisse:

Code: Alles auswählen

a =[1]*1000

ano = lambda (i,x): 0 if i&1 else x
def mapper(a):
    return map(ano, enumerate(a))

def lc(a):
    return [0 if i&1 else x for i, x in enumerate(a)]

def gen(a):
    for i,x in enumerate(a):
        if i&1:
            yield 0
        else:
            yield x

def copy(a):
    from copy import copy
    b = copy(a)
    b[1::2]=[0]*(len(a)/2)
    return b

if __name__=='__main__':
    from timeit import Timer
    t1 = Timer("z=mapper(a)", "from __main__ import mapper, a")
    t2 = Timer("z=lc(a)", "from __main__ import lc, a")
    t3 = Timer("z=list(gen(a))", "from __main__ import gen, a")
    t4 = Timer("z=copy(a)", "from __main__ import copy, a")
    print t1.timeit(number=1000)
    print t2.timeit(number=1000)
    print t3.timeit(number=1000)
    print t4.timeit(number=1000)
Output

Code: Alles auswählen

0.999876976013
0.591740846634
0.660285949707
0.0420200824738
[mod]copy[/mod] ist hier deutlich überlegen.

Verfasst: Samstag 14. November 2009, 16:20
von numerix
jerch hat geschrieben:[mod]copy[/mod] ist hier deutlich überlegen.
Und mit slicing geht es sogar noch schneller ...

Verfasst: Samstag 14. November 2009, 16:38
von jerch
numerix hat geschrieben:Und mit slicing geht es sogar noch schneller ...
Yupp, das hatte ich im Taumel der Ausprobiererei ganz verbessen... ;)

Code: Alles auswählen

b = a[:] # -> 0.0287139415741 für obigen test