我有一個填充了不同顏色的網格(由不同的整數表示)。我想快速(在一行和最少的處理時間)計算所有顏色的出現次數并回傳最高的出現次數。另外,我想忽略零。
這是我的解決方案(您能想到更好的解決方案嗎?):
grid = [[0, 0, 5, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 0, 0, 0], [0, 30, 30, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0], [0, 30, 0, 0, 33, 33, 0, 0, 50, 0, 50, 0, 0], [0, 30, 0, 0, 33, 33, 0, 0, 50, 50, 50, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0], [0, 0, 0, 0, 0, 0, 0, 88, 88, 88, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 88, 88, 0, 0, 0, 0]]
rows,cols=len(grid),len(grid[0])
ctrSum=Counter()
for row in grid:
ctrSum = Counter(row)
ctrSum -= Counter({0:(rows*cols)}) # subtract out a ridiculous amount of zeroes to eliminate them all from the counter
return max(ctrSum.values())
uj5u.com熱心網友回復:
由于 Pranav 的打字速度比我快,這是您問題的另一個潛在答案:
ans = max(Counter(x for row in grid for x in row if x!=0).values())
我想到了不規則的嵌套串列,這就是可以做到的:
unfurl=lambda x: sum(map(unfurl,x),[]) if isinstance(x,list) or isinstance(x, tuple) else [x]
ans = max(Counter(unfurl(grid)).values())
uj5u.com熱心網友回復:
您可以在創建計數器時展平串列串列,而不是在回圈中將每一行的計數添加到計數器!
ctr = Counter(x for row in grid for x in row)
# Counter({0: 79, 5: 1, 10: 4, 30: 4, 33: 5, 50: 6, 88: 5})
然后,洗掉0鍵,找到最大值:
del ctr[0]
max_key, max_count = max(ctr.items(), key=lambda item: item[1]) # 50, 6
計算零并稍后洗掉密鑰并不比根本不計算它們更快或更慢(在我的計算機上,timeit兩種方法回傳的時間相似)
grid = [[0, 0, 5, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 0, 0, 0], [0, 30, 30, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0], [0, 30, 0, 0, 33, 33, 0, 0, 50, 0, 50, 0, 0], [0, 30, 0, 0, 33, 33, 0, 0, 50, 50, 50, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0], [0, 0, 0, 0, 0, 0, 0, 88, 88, 88, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 88, 88, 0, 0, 0, 0]]
def m1(grid):
rows,cols=len(grid),len(grid[0])
ctrSum=Counter()
for row in grid:
ctrSum = Counter(row)
ctrSum -= Counter({0:(rows*cols)}) # subtract out a ridiculous amount of zeroes to eliminate them all from the counter
return max(ctrSum.items(), key=lambda x: x[1])
def m2(grid):
ctr = Counter(x for row in grid for x in row)
del ctr[0]
return max(ctr.items(), key=lambda item: item[1])
def m3(grid):
ctr = Counter(x for row in grid for x in row if x)
return max(ctr.items(), key=lambda item: item[1])
def m3_oneline(grid):
return max(Counter(x for row in grid for x in row if x).items(), key=lambda x: x[1])
t1 = timeit.timeit('func(grid)', setup='from __main__ import grid, m1 as func', number=10000)
t2 = timeit.timeit('func(grid)', setup='from __main__ import grid, m2 as func', number=10000)
t3 = timeit.timeit('func(grid)', setup='from __main__ import grid, m3 as func', number=10000)
t3_oneline = timeit.timeit('func(grid)', setup='from __main__ import grid, m3_oneline as func', number=10000)
print(t2/t1, t3/t1, t3_oneline/t1)
0.3436699657289107 0.3483052483876959 0.3614440352763763
m1(可以預見)花費的時間最長,因為您創建所有這些計數器只是為了將它們的值相加。m2并m3花費 34% 的時間m1。計數零和不計數零之間的運行時間沒有顯著差異,因為您需要檢查它是否是零,以便決定不計數。m3_oneline比and稍微慢一點(即單行不一定更有效。)m2m3
uj5u.com熱心網友回復:
您可以在一行中執行此操作,reduce()用于構建一個包含所有行中元素頻率的計數器,然后將 a 傳遞給以key消除max()在查找最頻繁元素時考慮的 0:
from collections import Counter
from functools import reduce
import math
result = max(reduce(lambda x, y: x Counter(y), grid, Counter()).items(),
key=lambda x: x[1] if x[0] else -math.inf)
print(result)
您還可以使用以下方法將所有計數器添加在一起sum():
result = max(sum(map(Counter, grid), Counter()).items(),
key=lambda x: x[1] if x[0] else -math.inf)
print(result)
使用上面的網格,這兩個都列印:
(50, 6)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/447855.html
標籤:Python python-3.x 表现 柜台
