ฉันมีรายการขนาด < Nและฉันต้องการเพิ่มขนาดเป็นขนาด N ด้วยค่า
แน่นอนฉันสามารถใช้สิ่งต่อไปนี้ได้ แต่ฉันรู้สึกว่ามีบางอย่างที่ฉันพลาดไป:
>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']
ฉันมีรายการขนาด < Nและฉันต้องการเพิ่มขนาดเป็นขนาด N ด้วยค่า
แน่นอนฉันสามารถใช้สิ่งต่อไปนี้ได้ แต่ฉันรู้สึกว่ามีบางอย่างที่ฉันพลาดไป:
>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']
คำตอบ:
a += [''] * (N - len(a))
หรือหากคุณไม่ต้องการเปลี่ยนa
สถานที่
new_a = a + [''] * (N - len(a))
คุณสามารถสร้างคลาสย่อยของรายการและเรียกใช้วิธีการใดก็ได้ที่คุณต้องการ
class MyList(list):
def ljust(self, n, fillvalue=''):
return self + [fillvalue] * (n - len(self))
a = MyList(['1'])
b = a.ljust(5, '')
ฉันคิดว่าแนวทางนี้เป็นภาพและไพโธนิกมากกว่า
a = (a + N * [''])[:N]
N < len(a)
กรณีนี้ไม่ได้สำหรับครั้งแรกเมื่อ เป็นกรณีของคำตอบที่สองที่คุณให้ไว้
ไม่มีฟังก์ชันในตัวสำหรับสิ่งนี้ แต่คุณสามารถเขียนบิวท์อินสำหรับงานของคุณได้ (หรืออะไรก็ได้: p)
(ดัดแปลงจาก itertool's padnone
และtake
สูตรอาหาร)
from itertools import chain, repeat, islice
def pad_infinite(iterable, padding=None):
return chain(iterable, repeat(padding))
def pad(iterable, size, padding=None):
return islice(pad_infinite(iterable, padding), size)
การใช้งาน:
>>> list(pad([1,2,3], 7, ''))
[1, 2, 3, '', '', '', '']
คำตอบของ gnibbler นั้นดีกว่า แต่ถ้าคุณต้องการ builtin คุณสามารถใช้itertools.izip_longest
( zip_longest
ใน Py3k):
itertools.izip_longest( xrange( N ), list )
ซึ่งจะส่งคืนรายการสิ่งที่เพิ่มเข้ามาเป็น( i, list[ i ] )
ไม่มี หากคุณต้องการกำจัดเคาน์เตอร์ให้ทำสิ่งต่อไปนี้
map( itertools.itemgetter( 1 ), itertools.izip_longest( xrange( N ), list ) )
operator.itemgetter()
ผมเชื่อว่าคุณหมายถึง นอกจากนี้ยังมีค่าจะต้องถูกแทนที่ด้วยNone
""
คุณยังสามารถใช้เครื่องกำเนิดไฟฟ้าแบบธรรมดาโดยไม่ต้องสร้างใด ๆ แต่ฉันจะไม่เติมรายการ แต่ปล่อยให้ตรรกะของแอปพลิเคชันจัดการกับรายการที่ว่างเปล่า
อย่างไรก็ตาม iterator โดยไม่ต้อง buildins
def pad(iterable, padding='.', length=7):
'''
>>> iterable = [1,2,3]
>>> list(pad(iterable))
[1, 2, 3, '.', '.', '.', '.']
'''
for count, i in enumerate(iterable):
yield i
while count < length - 1:
count += 1
yield padding
if __name__ == '__main__':
import doctest
doctest.testmod()
หากคุณต้องการเติม None แทน '' ให้ map () ทำงาน:
>>> map(None,[1,2,3],xrange(7))
[(1, 0), (2, 1), (3, 2), (None, 3), (None, 4), (None, 5), (None, 6)]
>>> zip(*map(None,[1,2,3],xrange(7)))[0]
(1, 2, 3, None, None, None, None)
more-itertools
เป็นไลบรารีที่มีpadded
เครื่องมือพิเศษสำหรับปัญหาประเภทนี้:
import more_itertools as mit
list(mit.padded(a, "", N))
# [1, '', '', '', '']
อีกวิธีหนึ่งmore_itertools
ยังใช้สูตร Python itertoolsรวมถึงpadnone
และtake
ตามที่กล่าวไว้โดย @kennytm ดังนั้นจึงไม่จำเป็นต้องนำมาใช้ใหม่:
list(mit.take(N, mit.padnone(a)))
# [1, None, None, None, None]
หากคุณต้องการแทนที่None
ช่องว่างภายในเริ่มต้นให้ใช้การทำความเข้าใจรายการ:
["" if i is None else i for i in mit.take(N, mit.padnone(a))]
# [1, '', '', '', '']
หากต้องการออกจาก kenny ™:
def pad(l, size, padding):
return l + [padding] * abs((len(l)-size))
>>> l = [1,2,3]
>>> pad(l, 7, 0)
[1, 2, 3, 0, 0, 0, 0]
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))
นี้หลีกเลี่ยงการจัดสรรเพิ่มเติมใด ๆ ซึ่งแตกต่างจากการแก้ปัญหาใด ๆ [value] * extra_length
ที่ขึ้นอยู่กับการสร้างและท้ายรายการ เมธอด "ขยาย" จะเรียก__length_hint__
ใช้ตัววนซ้ำก่อนและขยายการปันส่วนสำหรับส่วนl
นั้นก่อนที่จะกรอกจากตัววนซ้ำ
คุณสามารถใช้*
ตัวดำเนินการแกะกล่องซ้ำได้ :
N = 5
a = [1]
pad_value = ''
pad_size = N - len(a)
final_list = [*a, *[pad_value] * pad_size]
print(final_list)
เอาต์พุต:
[1, '', '', '', '']