บิวท์อินบางตัวเพื่อวางรายการใน python


110

ฉันมีรายการขนาด < Nและฉันต้องการเพิ่มขนาดเป็นขนาด N ด้วยค่า

แน่นอนฉันสามารถใช้สิ่งต่อไปนี้ได้ แต่ฉันรู้สึกว่ามีบางอย่างที่ฉันพลาดไป:

>>> N = 5
>>> a = [1]
>>> map(lambda x, y: y if x is None else x, a, ['']*N)
[1, '', '', '', '']

ทำไมคุณถึงต้องการทำเช่นนี้? คงมีวิธีที่ดีกว่านี้
Katriel

ฉันจัดลำดับรายการให้เป็นสตริงที่คั่นด้วยแท็บด้วยจำนวนคอลัมน์คงที่
ใหม่

คุณหมายถึงคุณกำลังทำอะไรบางอย่างเช่น '\ t'.join ([1,' ',' ',' ',' '])? บางทีคุณอาจบอกเราเพิ่มเติมเกี่ยวกับสิ่งที่คุณตั้งใจจะนำไปใช้จากนั้นเราจะลองคิดดู
satoru

@ Satoru.Logic: ใช่พิมพ์ >> a_stream '\ t'.join (the_list)คือทั้งหมดที่ฉันต้องการนำไปใช้
เปิดใหม่

คำตอบ:


167
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, '')

3
สิ่งนี้ดูดีขึ้นมาก แต่ฉันยังคงคาดหวังบางอย่างเช่นวิธีการเติมหรือแผ่นหรือฟังก์ชัน =)
ล่าสุด

31

ฉันคิดว่าแนวทางนี้เป็นภาพและไพโธนิกมากกว่า

a = (a + N * [''])[:N]

ฉันใช้เวลาครึ่งนาทีในการทำความเข้าใจ คำตอบที่ได้รับการยอมรับนั้นตรงไปตรงมากว่ามาก
Richard Möhn

4
@ RichardMöhn "pythonic" แปลว่า "สำนวน" ยิ่งคุณใช้ Python นานเท่าไหร่คุณก็จะพบว่าไวยากรณ์นี้เป็นธรรมชาติมากขึ้นเท่านั้น
Nuno André

5
ฉันรู้ว่า 'pythonic' หมายถึงอะไร และฉันใช้ Python อย่างต่อเนื่องตั้งแต่ปี 2014 ฉันยังไม่พบคำตอบของคุณที่เป็นธรรมชาติ
Richard Möhn

อะไรทำให้ pythonic สร้างรายการโยนทิ้งระดับกลาง
DylanYoung

1
@DylanYoung N < len(a)กรณีนี้ไม่ได้สำหรับครั้งแรกเมื่อ เป็นกรณีของคำตอบที่สองที่คุณให้ไว้
kon psych

26

ไม่มีฟังก์ชันในตัวสำหรับสิ่งนี้ แต่คุณสามารถเขียนบิวท์อินสำหรับงานของคุณได้ (หรืออะไรก็ได้: 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, '', '', '', '']

6

คำตอบของ 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 ) )

1
ฉันรู้เกี่ยวกับizip_longestแต่ส่งผลให้รหัสดูไม่ดี =)
ล่าสุด

2
operator.itemgetter()ผมเชื่อว่าคุณหมายถึง นอกจากนี้ยังมีค่าจะต้องถูกแทนที่ด้วยNone ""
pylang

5

คุณยังสามารถใช้เครื่องกำเนิดไฟฟ้าแบบธรรมดาโดยไม่ต้องสร้างใด ๆ แต่ฉันจะไม่เติมรายการ แต่ปล่อยให้ตรรกะของแอปพลิเคชันจัดการกับรายการที่ว่างเปล่า

อย่างไรก็ตาม 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()

4

หากคุณต้องการเติม 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)

2
พูดตรงไปตรงมาa + [''] * (N-len (a))ดูชัดเจนกว่ามาก นอกจากนี้ยังขาดการคัดเลือกนักแสดงในรายการ แต่ยังไงก็ขอบคุณ
ใหม่

4

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, '', '', '', '']


2
extra_length = desired_length - len(l)
l.extend(value for _ in range(extra_length))

นี้หลีกเลี่ยงการจัดสรรเพิ่มเติมใด ๆ ซึ่งแตกต่างจากการแก้ปัญหาใด ๆ [value] * extra_lengthที่ขึ้นอยู่กับการสร้างและท้ายรายการ เมธอด "ขยาย" จะเรียก__length_hint__ใช้ตัววนซ้ำก่อนและขยายการปันส่วนสำหรับส่วนlนั้นก่อนที่จะกรอกจากตัววนซ้ำ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.