Bir dizeyi python-3.x'de sözlük kullanarak nasıl biçimlendiririm?


215

Ben dizeleri biçimlendirmek için sözlük kullanma büyük bir hayranıyım. Kullandığım dize biçimini okumama ve mevcut sözlüklerden faydalanmama yardımcı oluyor. Örneğin:

class MyClass:
    def __init__(self):
        self.title = 'Title'

a = MyClass()
print 'The title is %(title)s' % a.__dict__

path = '/path/to/a/file'
print 'You put your file here: %(path)s' % locals()

Ancak aynı şeyi yapmak için python 3.x sözdizimini anlayamıyorum (ya da bu mümkün ise). Aşağıdakileri yapmak istiyorum

# Fails, KeyError 'latitude'
geopoint = {'latitude':41.123,'longitude':71.091}
print '{latitude} {longitude}'.format(geopoint)

# Succeeds
print '{latitude} {longitude}'.format(latitude=41.123,longitude=71.091)

Yanıtlar:


15

Soru Python 3'e özgü olduğundan, burada Python 3.6'dan beri mevcut olan yeni f-string sözdizimini kullanıyoruz :

>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091

Dış tek tırnakları ve iç çift tırnakları not edin (bunu başka şekilde de yapabilirsiniz).


F-string kullanımının python3 yaklaşımına daha uyumlu olduğunu söyleyebilirim.
Jonatas CD

2
F-dizelerinin 3.5 sürümünde değil, Python 3.6 için yeni olduğunu unutmayın.
Hugo

409

Bu senin için iyi mi?

geopoint = {'latitude':41.123,'longitude':71.091}
print('{latitude} {longitude}'.format(**geopoint))

2
Bunu denedim ve işe yaradı. Ama 'işaretçi gösteriminin' kullanımını anlamıyorum. Python'un işaretçi kullanmadığını biliyorum, bu bir kwarg örneği mi?
Homunculus Reticulli

2
@HomunculusReticulli Bu, bir işaretçi C ++ stiline işaretçi değil, biçim parametresidir (Minimum alan genişliği). docs.python.org/release/2.4.4/lib/typesseq-strings.html
D.Rosado

29
Python 3.2 tanıtıldı format_map. Buna benzer str.format(**mapping), bunun dışında mappingdoğrudan kullanılır ve kopyalanamaz dict. Bu, örneğin mappingbir diksiyon alt sınıfı ise yararlıdır
diapir

1
@eugene ** bir python sözlüğüne ne yapar? Bir nesne oluşturduğunu düşünmüyorum çünkü print (** geopoint) sözdizimi hatası
vermiyor

4
@NityeshAgarwal bu isimde bir sözlük yayılır = yani tek tek, bağımsız değişken olarak değer çiftleri print(**geopoint)ile aynıdır print(longitude=71.091, latitude=41.123). Birçok dilde, uyarıcı operatörü olarak bilinir . JavaScript'te buna yayılma operatörü denir . Python'da, bu operatöre belirli bir ad verilmemiştir.
abhisekp

79

Bir sözlüğü anahtar kelime bağımsız değişkenlerine açmak için kullanın **. Ayrıca, yeni stil biçimlendirme, nesnelerin niteliklerine ve eşleme öğelerine atıfta bulunur:

'{0[latitude]} {0[longitude]}'.format(geopoint)
'The title is {0.title}s'.format(a) # the a from your first example

2
Yer tutucu için konum endeksi eklemek kodu daha açık ve kullanımı daha kolay hale getirir, bu cevabı daha iyi buluyorum. Özellikle de böyle bir şey varsa:'{0[latitude]} {1[latitude]} {0[longitude]} {1[longitude]}'.format(geopoint0, geopoint1)
Løiten

1
Bu, bir defaultdictanahtar kullanıyorsanız ve tüm anahtarlara sahip değilseniz kullanışlıdır
Whymarrh

65

Python 3.0 ve 3.1 EOL'lu olduğundan ve hiç kimse bunları kullanmadığından str.format_map(mapping)(Python 3.2+) kullanabilirsiniz ve kullanmalısınız :

Benzer şekilde str.format(**mapping), eşleme doğrudan kullanılır ve a'ya kopyalanmazdict . Bu, örneğin eşleme bir dictalt sınıfsa yararlıdır .

Bunun anlamı, defaultdicteksik olan anahtarlar için varsayılan bir değer ayarlayan (ve döndüren) a'yı kullanabilmenizdir:

>>> from collections import defaultdict
>>> vals = defaultdict(lambda: '<unset>', {'bar': 'baz'})
>>> 'foo is {foo} and bar is {bar}'.format_map(vals)
'foo is <unset> and bar is baz'

Sağlanan eşleme dictbir alt sınıf değil , bir a olsa bile , bu muhtemelen biraz daha hızlı olacaktır.

Farklılık olsa da, büyük değil

>>> d = dict(foo='x', bar='y', baz='z')

sonra

>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format_map(d)

yaklaşık 10 ns (% 2) daha hızlı

>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format(**d)

Python 3.4.3'ümde. Sözlükte daha fazla anahtar olduğu için fark muhtemelen daha büyük olacaktır ve


Biçim dilinin bundan daha esnek olduğunu unutmayın; Bunu onlar, böylece endeksli ifadeleri, nitelik kere ve içerebilir edebilir bunlardan 2 bütün nesneyi biçimlendirmek ya:

>>> p1 = {'latitude':41.123,'longitude':71.091}
>>> p2 = {'latitude':56.456,'longitude':23.456}
>>> '{0[latitude]} {0[longitude]} - {1[latitude]} {1[longitude]}'.format(p1, p2)
'41.123 71.091 - 56.456 23.456'

3.6'dan başlayarak enterpolasyonlu dizeleri de kullanabilirsiniz:

>>> f'lat:{p1["latitude"]} lng:{p1["longitude"]}'
'lat:41.123 lng:71.091'

Sadece iç içe tırnak içindeki diğer tırnak karakterlerini kullanmayı unutmamalısınız . Bu yaklaşımın bir başka yönü de bir biçimlendirme yöntemi çağırmaktan çok daha hızlı olmasıdır .


İyi olan, üzerinde performans iyileştirmeleri var formatmı? (Bir dict'e kopyalanmadığı göz önüne alındığında)
Bhargav Rao

2
@BhargavRao fazla değil, 2%: D
Antti Haapala

@BhargavRao performans arıyorsanız, bunu kullanın '%(latitude)s %(longitude)s'%geopoint;)
Tcll

20
print("{latitude} {longitude}".format(**geopoint))

6

Python 2 sözdizimi Python 3'te de çalışır:

>>> class MyClass:
...     def __init__(self):
...         self.title = 'Title'
... 
>>> a = MyClass()
>>> print('The title is %(title)s' % a.__dict__)
The title is Title
>>> 
>>> path = '/path/to/a/file'
>>> print('You put your file here: %(path)s' % locals())
You put your file here: /path/to/a/file

artı da belirgin şekilde daha performans ; f""veya "".format();)
Tcll

2
geopoint = {'latitude':41.123,'longitude':71.091}

# working examples.
print(f'{geopoint["latitude"]} {geopoint["longitude"]}') # from above answer
print('{geopoint[latitude]} {geopoint[longitude]}'.format(geopoint=geopoint)) # alternate for format method  (including dict name in string).
print('%(latitude)s %(longitude)s'%geopoint) # thanks @tcll

1
birini kaçırdınız;) print('%(latitude)s %(longitude)s'%geopoint)Bu da diğer 2'den daha hızlıdır
Tcll

@tcll Aslında dizede sözlük adını kullanabileceğim örnekleri istedim. Böyle bir şey'%(geopoint["latitude"])s %(geopoint["longitude"])s'%{"geopoint":geopoint}
Şeyh Abdul Wahid

1

Çoğu cevap yalnızca diktenin değerlerini biçimlendirmiştir.

İsterseniz de tuşunu biçimlendirmek kullanabilirsiniz dizesine dict.items () :

geopoint = {'latitude':41.123,'longitude':71.091}
print("{} {}".format(*geopoint.items()))

Çıktı:

('enlem', 41.123) ('boylam', 71.091)

Keyfi bir şekilde biçimlendirmek istiyorsanız, yani tuples gibi anahtar / değer çiftlerini göstermemek istiyorsanız:

from functools import reduce
print("{} is {} and {} is {}".format(*reduce((lambda x, y: x + y), [list(item) for item in geopoint.items()])))

Çıktı:

enlem 41.123 ve boylam 71.091


not 'enlem' önce 'enlem' önce gelme şansı vardır geopoint.items();)
Tcll
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.