แปลง tuple เป็น list และ back


206

ขณะนี้ฉันกำลังทำงานกับโปรแกรมแก้ไขแผนที่สำหรับเกมใน pygame โดยใช้แผนที่ย่อย ระดับนั้นถูกสร้างขึ้นจากบล็อกในโครงสร้างต่อไปนี้ (แม้ว่าจะมีขนาดใหญ่กว่า):

level1 = (
         (1,1,1,1,1,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,0,0,0,0,1)
         (1,1,1,1,1,1))

โดยที่ "1" เป็นบล็อกที่เป็นกำแพงและ "0" เป็นบล็อกที่มีอากาศว่าง

รหัสต่อไปนี้นั้นเป็นรหัสที่จัดการกับการเปลี่ยนแปลงประเภทบล็อก

clicked = pygame.mouse.get_pressed()
if clicked[0] == 1:
    currLevel[((mousey+cameraY)/60)][((mousex+cameraX)/60)] = 1

แต่เนื่องจากระดับถูกเก็บไว้ในสิ่งอันดับฉันไม่สามารถเปลี่ยนค่าของบล็อกต่าง ๆ ได้ ฉันจะเปลี่ยนค่าต่าง ๆ ในระดับอย่างง่ายได้อย่างไร?


12
อย่าใช้สิ่งอันดับเพียงใช้รายการจากจุดเริ่มต้น มันอาจช้าลงรหัสของคุณถ้าระดับของคุณมีขนาดใหญ่มากถ้าคุณต้องแปลงพวกเขา
jamylak

4
วิธีไปกับรายการแทนสิ่งอันดับจากจุดเริ่มต้นมาก?
Krzysztof Bujniewicz

4
@ user2133308 btw เพียงแค่ทราบความเข้ากันได้คุณควรใช้การแบ่งจำนวนเต็ม//แทนเพียง/เพราะใน Python 3 /จะดำเนินการแบ่งจุดลอยตัวและไขรหัสของคุณ
jamylak

คำตอบ:


284

แปลง tuple เป็นรายการ:

>>> t = ('my', 'name', 'is', 'mr', 'tuple')
>>> t
('my', 'name', 'is', 'mr', 'tuple')
>>> list(t)
['my', 'name', 'is', 'mr', 'tuple']

แปลงรายการเป็น tuple:

>>> l = ['my', 'name', 'is', 'mr', 'list']
>>> l
['my', 'name', 'is', 'mr', 'list']
>>> tuple(l)
('my', 'name', 'is', 'mr', 'list')

5
มันไม่ทำงานสำหรับฉัน หากฉันเรียกใช้รหัสในบล็อกแรกเพื่อแปลง tuple t เป็นรายการโดยส่ง t to list () ฉันได้รับข้อความแสดงข้อผิดพลาด: "*** ข้อผิดพลาดในการโต้แย้ง: '(t)'" สิ่งนี้ดูเหมือนจะเกิดขึ้นกับ ฉันเท่านั้นในขณะที่การแก้จุดบกพร่อง ยังคงสับสน
จิมมี่

4
@Jimmy นั่นเป็นเพราะ list เป็นคำสั่งดีบักเกอร์ให้รันp list(...)แทน
มอริตซ์

74

คุณมีสิ่งอันดับ tuple
วิธีแปลงทุก tuple เป็นรายการ:

[list(i) for i in level] # list of lists

--- หรือ ---

map(list, level)

และหลังจากที่คุณแก้ไขเสร็จแล้วให้แปลงกลับเป็น:

tuple(tuple(i) for i in edited) # tuple of tuples

--- หรือ --- (ขอบคุณ @jamylak)

tuple(itertools.imap(tuple, edited))

คุณยังสามารถใช้อาร์เรย์ numpy:

>>> a = numpy.array(level1)
>>> a
array([[1, 1, 1, 1, 1, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 0, 0, 0, 0, 1],
       [1, 1, 1, 1, 1, 1]])

สำหรับการจัดการ:

if clicked[0] == 1:
    x = (mousey + cameraY) // 60 # For readability
    y = (mousex + cameraX) // 60 # For readability
    a[x][y] = 1

2
NumPy เป็นแพ็คเกจพื้นฐานสำหรับการคำนวณทางวิทยาศาสตร์ด้วย Python วัตถุหลักของ NumPy คืออาเรย์หลายมิติที่เป็นเนื้อเดียวกัน มันเป็นสารบัญ (โดยทั่วไปคือตัวเลข) ซึ่งเป็นชนิดเดียวกันทั้งหมดจัดทำดัชนีโดย tuple ของจำนวนเต็มบวก
pradyunsg

24

คุณสามารถมีรายการได้ แปลง tuple ของ tuples เป็นรายการของรายการโดยใช้:

level1 = [list(row) for row in level1]

หรือ

level1 = map(list, level1)

และแก้ไขตามนั้น

แต่อาร์เรย์ที่มีค่ามากนั้นยอดเยี่ยมกว่า


18

ในการแปลงสิ่งอันดับเป็นรายการ

(เครื่องหมายจุลภาคหายไประหว่างทูเปิลในคำถามที่กำหนดมันถูกเพิ่มเพื่อป้องกันข้อความแสดงข้อผิดพลาด)

วิธีที่ 1:

level1 = (
     (1,1,1,1,1,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,0,0,0,0,1),
     (1,1,1,1,1,1))

level1 = [list(row) for row in level1]

print(level1)

วิธีที่ 2:

level1 = map(list,level1)

print(list(level1))

วิธีที่ 1 ใช้เวลา --- 0.0019991397857666016 วินาที ---

วิธีที่ 2 ใช้เวลา --- 0.0010001659393310547 วินาที ---


14

ทำไมคุณไม่ลองแปลงประเภทของมันจาก tuple เป็น list และในทางกลับกัน

level1 = (
     (1,1,1,1,1,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,0,0,0,0,1)
     (1,1,1,1,1,1))

print(level1)

level1 = list(level1)

print(level1)

level1 = tuple(level1)

print(level1)

5

ทั้งคำตอบนั้นดี แต่คำแนะนำเล็กน้อย:

Tuples นั้นไม่เปลี่ยนรูปซึ่งหมายความว่าพวกมันไม่สามารถเปลี่ยนแปลงได้ ดังนั้นหากคุณต้องการจัดการข้อมูลมันจะเป็นการดีกว่าที่จะเก็บข้อมูลไว้ในรายการมันจะลดค่าใช้จ่ายที่ไม่จำเป็น

ในกรณีของคุณแยกข้อมูลไปยังรายการดังที่แสดงโดย eumiro และหลังจากแก้ไขสร้าง tuple ที่คล้ายกันของโครงสร้างที่คล้ายกันเป็นคำตอบที่ได้รับจากเด็กนักเรียน

นอกจากนี้ยังแนะนำให้ใช้อาร์เรย์ numpy เป็นตัวเลือกที่ดี


คุณควรเขียนคำตอบนี้ด้วยซึ่งnumpyจะเป็นทางออกที่เร็วที่สุดในการทำงานกับข้อมูลประเภทนี้
jamylak

แน่นอนคุณสามารถใช้โครงสร้างข้อมูลที่เปลี่ยนแปลงไม่ได้เช่น tuples แม้ว่าคุณจะจัดการข้อมูล สถานที่ตั้งทั้งหมดของการเขียนโปรแกรมการทำงานและสิ่งที่ส่วนใหญ่สร้างบนการคงอยู่ของข้อมูล แต่แน่นอนใน Python land คุณอาจต้องการไปกับฝูงและกลายพันธุ์ได้อย่างอิสระ ...
nperson325681

5

รายการไปยัง Tuple และย้อนกลับสามารถทำได้ดังนี้

import ast, sys
input_str = sys.stdin.read()
input_tuple = ast.literal_eval(input_str)

l = list(input_tuple)
l.append('Python')
#print(l)
tuple_2 = tuple(l)

# Make sure to name the final tuple 'tuple_2'
print(tuple_2)

2

คุณสามารถเร่งความเร็วสิ่งของของคุณได้อย่างรวดเร็วหากคุณใช้เพียงแค่รายการเดียวแทนที่จะเป็นรายการ นี่เป็นไปได้แน่นอนถ้ารายการภายในทั้งหมดของคุณมีขนาดเท่ากัน (ซึ่งเป็นจริงในตัวอย่างของคุณดังนั้นฉันแค่สมมตินี่)

WIDTH = 6
level1 = [ 1,1,1,1,1,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,0,0,0,0,1,
           1,1,1,1,1,1 ]
print level1[x + y*WIDTH]  # print value at (x,y)

และคุณอาจเร็วกว่านี้ถ้าคุณใช้ bitfield แทนรายการ:

WIDTH = 8  # better align your width to bytes, eases things later
level1 = 0xFC84848484FC  # bit field representation of the level
print "1" if level1 & mask(x, y) else "0"  # print bit at (x, y)
level1 |= mask(x, y)  # set bit at (x, y)
level1 &= ~mask(x, y)  # clear bit at (x, y)

กับ

def mask(x, y):
  return 1 << (WIDTH-x + y*WIDTH)

แต่นั่นจะทำงานได้ก็ต่อเมื่อฟิลด์ของคุณมี 0 หรือ 1 แน่นอน หากคุณต้องการค่ามากขึ้นคุณจะต้องรวมหลายบิตซึ่งจะทำให้ปัญหาซับซ้อนมากขึ้น

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