SORU
8 HAZİRAN 2011, ÇARŞAMBA


Atama lambda ifadesi içinde Python

Nesnelerin bir listesi var, ve biri hariç boş, filter lambda bir ifade kullanarak tüm nesneleri kaldırmak istiyorum.

Eğer giriş örneğin:

[Object(name=""), Object(name="fake_name"), Object(name="")]

...sonra çıktı olmalıdır:

[Object(name=""), Object(name="fake_name")]

Bir şekilde lambda bir ifade eklemek için bir görev var mı? Örneğin:

flag = True 
input = [Object(name=""), Object(name="fake_name"), Object(name="")] 
output = filter(
    (lambda o: [flag or bool(o.name), flag = flag and bool(o.name)][0]),
    input
)

CEVAP
31 Ocak 2013, PERŞEMBE


Python 2'de liste üreteçleri bir yan etkisi olarak yerel atamaları gerçekleştirebilirsiniz.

import sys
say_hello = lambda: [
    [None for message in ["Hello world"]],
    sys.stdout.write(message   "\n")
][-1]
say_hello()

Ancak, olası örnek değişkeni flag dış kapsamı, lambdadeğil'nin kapsamı. çünkü bu kullanmak için değil Bu lambda Python 2'de genel davranışı ile yapmak zorunda değil. Python 3 lets get around bu nonlocal kelime içinde defama nonlocal olamaz kullanılan içinde lambdas ve Python 3 kaldırır bu yan etki listesi kapsam, yani bu mümkün değil Python 3.

Geçici bir çözüm var (aşağıya bakınız), ama konu açılmışken...


Bazı durumlarda bu her şeyi lambda: bir iç yapmak için kullanabilirsiniz

(lambda: [
    ['def'
        for sys in [__import__('sys')]
        for math in [__import__('math')]

        for sub in [lambda *vals: None]
        for fun in [lambda *vals: vals[-1]]

        for echo in [lambda *vals: sub(
            sys.stdout.write(u" ".join(map(unicode, vals))   u"\n"))]

        for Cylinder in [type('Cylinder', (object,), dict(
            __init__ = lambda self, radius, height: sub(
                setattr(self, 'radius', radius),
                setattr(self, 'height', height)),

            volume = property(lambda self: fun(
                ['def' for top_area in [math.pi * self.radius ** 2]],

                self.height * top_area))))]

        for main in [lambda: sub(
            ['loop' for factor in [1, 2, 3] if sub(
                ['def'
                    for my_radius, my_height in [[10 * factor, 20 * factor]]
                    for my_cylinder in [Cylinder(my_radius, my_height)]],

                echo(u"A cylinder with a radius of %.1fcm and a height "
                     u"of %.1fcm has a volume of %.1fcm³."
                     % (my_radius, my_height, my_cylinder.volume)))])]],

    main()])()

10.0 cm çapında ve 20.0 cm yüksekliğinde bir silindir 6283 bir birim var.2cm3.
20.0 cm çapında ve 40.0 cm yüksekliğinde bir silindir 50265 bir birim var.5cm3.
30.0 cm çapında ve 60.0 cm yüksekliğinde bir silindir 169646 bir birim var.0cm3.

Lütfen yapma.


...geri orijinal örnek: dış kapsamında flag değişken atamaları gerçekleştirebilirsiniz rağmen, fonksiyonları daha önce atanmış bir değeri değiştirmek için kullanabilirsiniz.

Örneğin, flag setattr kullanarak ayarlanmış olan bir nesne olabilir:

flag = Object(value=True)
input = [Object(name=''), Object(name='fake_name'), Object(name='')] 
output = filter(lambda o: [
    flag.value or bool(o.name),
    setattr(flag, 'value', flag.value and bool(o.name))
][0], input)
[Object(name=''), Object(name='fake_name')]

Eğer yukarıdaki temaya uygun istersek, bir liste setattr yerine anlama kullanabiliriz:

    [None for flag.value in [bool(o.name)]]

Ama gerçekten, ciddi kodu her zaman görev yapıyor olacak iseniz lambda yerine normal bir işlev tanımı kullanmalısınız.

flag = Object(value=True)
def not_empty_except_first(o):
    result = flag.value or bool(o.name)
    flag.value = flag.value and bool(o.name)
    return result
input = [Object(name=""), Object(name="fake_name"), Object(name="")] 
output = filter(not_empty_except_first, input)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ChrisCrossMedia

    ChrisCrossMe

    17 EYLÜL 2009
  • jesiel santos

    jesiel santo

    15 Ocak 2009
  • Mark Halberstadt

    Mark Halbers

    19 ŞUBAT 2010