iT邦幫忙

1

Python透過迴圈生成二維陣列

  • 分享至 

  • xImage

row = 4096
column = 12
column的值為0或是1
如何生成所有組合
也就是
[
[0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1],
[0,0,0,0,0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,0,1,0,1],
[0,0,0,0,0,0,0,0,0,1,1,0],
[0,0,0,0,0,0,0,0,0,1,1,1],
.
.
.
[1,1,1,1,1,1,1,1,1,1,1,1]
]
共有4096個組合
該如何撰寫程式碼,才能成功生成此二維陣列
謝謝!!

player iT邦大師 1 級 ‧ 2023-02-10 16:31:11 檢舉
GOOGLE找
PYTHON+建立2維陣列
很難?
你都知道跑回圈填值了
簡單的做法是跑一個0~4095的迴圈
然後裡頭把數值拆成2進位的12個值
去填植
alien663 iT邦研究生 3 級 ‧ 2023-02-10 16:56:26 檢舉
colume ~~~~
s9816358 iT邦新手 5 級 ‧ 2023-02-10 17:01:50 檢舉
已編輯
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
一級屠豬士
iT邦大師 1 級 ‧ 2023-02-11 00:08:18
最佳解答
l = [list(map(int, f'{i:012b}')) for i in range(4096)]
for x in [0,1024,2048,3072,4095]:
  print(x, '->', l[x])

後續補充

在Python中
整數以 binary string方式表示可以直接呼叫內建函數 bin()
https://docs.python.org/3/library/functions.html#bin

在上面文件中可以看到,還可以使用 format(),以及f-string 的方式.

因為要轉換的數字最大的是 4095,所以可以先用
len(f'{4095:b}') 得到12

所以我們可以用 f-string 或 format() 的格式
https://docs.python.org/zh-tw/3/tutorial/inputoutput.html
https://docs.python.org/zh-tw/3/whatsnew/3.8.html#bpo-36817-whatsnew
指定為長度12,前面補0,binary 格式.

f'{4095:012b}'
'111111111111'

f'{0:012b}'
'000000000000'

可以看到得到了起始與結束的數字轉換為string的結果了.
格式化輸出已經幫我們使用了 bin() 再搭配 zfill()
得到想要的string. 
在Python中,string 可以說是char 組成的list.
在Python,list 是最常使用的一種資料結構,有大量的函數
以及方法圍繞著list發展. 

我們可以透握 int() 將字元轉換為整數
https://docs.python.org/3/library/functions.html#int
>>> int('1')
1
>>> type(int('1'))
<class 'int'>

這時候有幾種方式,一種是用迴圈一個個轉換,然後append()進去

lst = []
for elem in '111111111111':
  lst.append(int(elem))

lst
會得到
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

也可以用列表推導(list comprehension)
https://zh.wikipedia.org/zh-tw/%E5%88%97%E8%A1%A8%E6%8E%A8%E5%AF%BC%E5%BC%8F

lst2 = [int(elem) for elem in '111111111111']
lst2

會得到
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

或是使用 map()
https://docs.python.org/3/library/functions.html#map

iter1 = map(int, '111111111111')

但這時候得到的結果並不是list, 還需要再使用list() 來轉換為list.
為何不直接轉為list? 在Python2 是直接轉為list,在Python3 改為iterator
https://zh.wikipedia.org/wiki/%E8%BF%AD%E4%BB%A3%E5%99%A8
至於為何要做變動,在此先不做討論.

既然已經可以得到轉換為list 的方法了.
這時候來做0到4095的部分,一樣可以分為用迴圈,或是列表推導.

為了方便表示,先用0~4

lst3 = []
for i in range(5):
  lst3.append(list(map(int, f'{i:012b}')))

lst3
會得到
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0]]

或是
lst4 = [list(map(int, f'{i:012b}')) for i in range(5)]

會得到一樣的結果.

所以最後可以使用
l = [list(map(int, f'{i:012b}')) for i in range(4096)]
看更多先前的回應...收起先前的回應...
s9816358 iT邦新手 5 級 ‧ 2023-02-11 14:27:22 檢舉

一級屠豬士
請問可以貼有關這段程式碼說明的相關文章嗎 謝謝您!!

做了些補充,因為下面的格子,寬度變小了,所以補充在上面.

s9816358 iT邦新手 5 級 ‧ 2023-02-13 11:10:01 檢舉

一級屠豬士
謝謝您!!

s9816358 iT邦新手 5 級 ‧ 2023-02-16 14:24:45 檢舉

一級屠豬士
l = [list(map(int, f'{i:002d}')) for i in range(10,30)]
結果為:
[[1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9]]
我希望得到的是
[[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9]]
請問如何剔除包含0的呢

l = [list(map(int, f'{i:002d}')) for i in range(10,30)]
lf = list(filter(lambda x: x[0] != 0 and x[1] != 0 , l))
print(lf)
0
揮揮手
iT邦研究生 5 級 ‧ 2023-02-10 16:38:15

問題
轉2進位制嗎?
不然可能要講清楚一點
colume的值有0、1的可能
多可能 怎樣會是0 怎樣會是1
我因為看你給的陣列是2進位 才提問

剛剛看chatGPT 爆滿中
不然可能直接問比較快

照 player 大
講的做就好

大概講邏輯
最簡單的就是跑 0~(4096-1)的迴圈
在迴圈內 針對 當前值
用取得2進位的值temp = str(format(當前值, "b")).zfill(12)
然後用list()拆分
colume = list(temp)
然後在用一個陣列接這個 colume
收工

邏輯給你
code 自己打一下

s9816358 iT邦新手 5 級 ‧ 2023-02-10 17:01:38 檢舉

已編輯

0
Catherine Bloom
iT邦新手 2 級 ‧ 2023-02-10 20:23:50

謝謝re.Zero大大的建議,修改如下。

import numpy as k
a, c = 4096, 12
# b = k.empty((a, c)).tolist() # make an array, then trans array to list
b = [list(range(c)) for n in range(a)]

# binary caculator in list
m = 0

# 以下方法笨笨的,應該另有聰明的數學方式解答對吧???
for i in range(4096):
    n=str(bin(m))[2:]
    if len(str(n)) <12:
        n='0'*(12-len(n))+n
        #print(n)
    for j in range(12):
        b[i][j]= int(n[j])
    m+=1
 
import pprint     
pprint.pprint(b)
re.Zero iT邦研究生 5 級 ‧ 2023-02-11 02:09:24 檢舉

你的問題出在 b = [['x']*3]*8 這裡:

  • ['x']*3 這段生成一個內含 3 個元素('x')的 list#1。
  • [['x']*3]*8 這段生成一個內含 8 個元素的 list#2,而這 8 個元素都「參照」至「同一個」內含 3 個元素的 list#1。
  • b = [['x']*3]*8 之後的操作,不管你的 for-loop-i 從 0 跑到 7,你的 for-loop-j 都一直在修改那一個內含 3 個元素的 list#1。

(到這裡還看不懂?沒關係,先繼續看後面提供的連結內容~)

神奇現象範例:

from pprint import pprint as pp
b = [[0]*9]*3
pp(b)
print('========')
b[1][2]=1
pp(b)

我的輸出:

[[0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0, 0]]
========
[[0, 0, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0, 0, 0],
 [0, 0, 1, 0, 0, 0, 0, 0, 0]]

謝謝大佬

2
froce
iT邦大師 1 級 ‧ 2023-02-10 23:27:08
[[int(s) for s in f'{i:012b}'] for i in range(4096)]

哆啦a夢吃驚臉,欠你一個最佳解答。

1
JamesDoge
iT邦高手 1 級 ‧ 2023-02-11 10:37:13

產生所有組合:

row = 4096
column = 12
combinations = []
for i in range(row):
    combination = []
    for j in range(column):
        combination.append(i >> j & 1)
    combination.reverse() # 反轉子列表,不會「左右鏡像」        
    combinations.append(combination)

印出

for combination in combinations:
    print(combination)

謝謝大大的offset。但是成果是「左右鏡像」的???

我要發表回答

立即登入回答