2017-03-23 12 views
3

我遇到了這個問題,我無意中發現了這個問題。
問題是這樣的。
我有這樣的列表:有沒有一種方法可以找到給定的整個部分給定的浮點數列表的最大小數部分?

L = [2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10.3, 10.4, 10.5, 11.1, 11.2, 11.3, 11.4, 11.5, 12.1, 12.2, 12.3, 12.4, 12.5] 

必需:
ANS = [[2,5],[3,4],[4,4],...]

即整數和最大小數部分。

我們該怎麼做?

到目前爲止,我已經試過這樣:

# Imports 
import numpy as np 
import math 

L = [2.1, 2.2, 2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10.3, 10.4, 10.5, 11.1, 11.2, 11.3, 11.4, 11.5, 12.1, 12.2, 12.3, 12.4, 12.5] 

whole = [ int(str(x).split(".")[0]) for x in L] 
frac = [ int(str(x).split(".")[-1]) for x in L] 
wf = [[w,f] for w,f in zip(whole,frac)] 

wset = list(set(whole)) 

print(whole) 
print(frac) 
print(wf) 
print(wset) 

回答

2

這裏是一個numpy解決方案:

L.sort() # skip this if L is already sorted 
Li = L.astype(int) 
uniq = np.r_[np.where(np.diff(Li))[0], Li.size-1] 
int_part = Li[uniq] 
max_frac = np.round((L[uniq]-int_part) * 10).astype(int) 
np.c_[int_part, max_frac].tolist() 
# [[2, 5], [3, 4], [4, 4], [5, 6], [6, 5], [7, 5], [8, 5], [9, 5], [10, 5], [11, 5], [12, 5]] 

一些計時:

import numpy as np 
import itertools as it 
from timeit import timeit 

def pp(L): 
    Li = L.astype(int) 
    uniq = np.r_[np.where(np.diff(Li))[0], Li.size-1] 
    int_part = Li[uniq] 
    max_frac = np.round((L[uniq]-int_part) * 10).astype(int) 
    return np.c_[int_part, max_frac].tolist() 

def johnchase(L): 
    vals = [] 
    foo = [str(e).split('.') for e in L] 
    for key, group in it.groupby(foo, lambda x: (x[0])): 
     vals.append([int(e) for e in max(group)]) 
    return vals 

def bernie(L): 
    return [[k, int(round(max(i % 1 for i in g)*10,1))] 
      for k, g in it.groupby(L,lambda x:int(x))] 

def kprabhakaran(L): 
    return [map(int,str(max(list(cgen))).split('.')) 
    for c,cgen in it.groupby(L,lambda x:int(x))] 

def prep(N, k): 
    global L 
    L = np.sort(np.random.choice(np.arange(N)/10, k, False)) 

N, k, n = 2 * 10**6, 10**6, 10 

for func in pp, johnchase, bernie, kprabhakaran: 
    print('{:20s}'.format(func.__name__), '{:6.4f} secs'.format(timeit(
     lambda: func(L), lambda: prep(N, k), number=n)/n)) 

打印:

pp     0.0379 secs 
johnchase   1.7252 secs 
bernie    1.4773 secs 
kprabhakaran   0.7592 secs 
4

可以使用itertools.groupby一鍵功能:

import itertools as it 

for k,g in it.groupby(L,lambda x:int(x)): 
    round(max(i % 1 for i in g),1) 

結果:

>>> for k,g in it.groupby(L,lambda x:int(x)): 
... print(str(k)+','+str(int(round(max(i % 1 for i in g)*10,1)))) 
... 
2,5 
3,4 
4,4 
5,6 
6,5 
7,5 
8,5 
9,5 
10,5 
11,5 
12,5 
0

你可以提供一個關鍵功能最大功能。

max_frac = max(filter(lambda x: int(x) == 2, L), 
       key=lambda x: int(str(x).split(".")[1])) 

使用模與此解決方案,爲@bernie做:

max_frac = max(filter(lambda x: int(x) == 2, L), 
       key=lambda x: x % 1) 

編輯:如果您想爲每一個浮在列表中做到這一點,更好的辦法是先進行排序,並使用groupby。

1

如果我理解正確的問題,你可以使用itertools.groupby

from itertools import groupby 

vals = [] 
foo = [str(e).split('.') for e in L] 
for key, group in groupby(foo, lambda x: (x[0])): 
    vals.append([int(e) for e in max(group)]) 

vals 
[[2, 5], 
[3, 4], 
[4, 4], 
[5, 6], 
[6, 5], 
[7, 5], 
[8, 5], 
[9, 5], 
[10, 5], 
[11, 5], 
[12, 5]] 
+0

它[R然而,如果我在vale以上的for循環中添加另一條打印線,那麼它並不是很出色。append line:print(key,list(group))IT GIVES VALUE ERROR:ValueError:max()arg是一個空序列 –

+0

'group'在這種情況下是一個生成器,所以一旦你調用它,它就必須被重新創建,例如試試這個:'foo =(e for e in range(10)) for i in foo: print(i)'然後不重新運行'foo'賦值再次運行for循環,不會打印任何內容。你可以通過將組變量重新分配給一個列表來解決這個問題:'group = list(group) print(group)'然而除非必要,否則這將不會有效 – johnchase

1

可以在groupby(itertools)

使用拉姆達在簡化列表理解爲更好地理解,

print [(c,list(cgen)) for c,cgen in groupby(sorted(L),lambda x:int(x))] 
[(2, [2.1, 2.2, 2.3, 2.4, 2.5]), (3, [3.1, 3.2, 3.3, 3.4]), (4, [4.1, 4.2, 4.3, 4.4]), (5, [5.1, 5.2, 5.3, 5.4, 5.5, 5.6]), (6, [6.1, 6.2, 6.3, 6.4, 6.5]), (7, [7.1, 7.2, 7.3, 7.4, 7.5]), (8, [8.1, 8.2, 8.3, 8.4, 8.5]), (9, [9.1, 9.2, 9.3, 9.4, 9.5]), (10, [10.1, 10.2, 10.3, 10.4, 10.5]), (11, [11.1, 11.2, 11.3, 11.4, 11.5]), (12, [12.1, 12.2, 12.3, 12.4, 12.5])] 

print [max(list(cgen)) for c,cgen in groupby(sorted(L),lambda x:int(x))] 
[2.5, 3.4, 4.4, 5.6, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5] 

print [str(max(list(cgen))).split('.') for c,cgen in groupby(sorted(L),lambda x:int(x))] 
[['2', '5'], ['3', '4'], ['4', '4'], ['5', '6'], ['6', '5'], ['7', '5'], ['8', '5'], ['9', '5'], ['10', '5'], ['11', '5'], ['12', '5']] 

因此

L = [2.1, 2.2, 3.1,2.3, 2.4, 2.5, 3.1, 3.2, 3.3, 3.4, 4.1, 4.2, 4.3, 4.4, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 6.1, 6.2, 6.3, 6.4, 6.5, 7.1, 7.2, 7.3, 7.4, 7.5, 8.1, 8.2, 8.3, 8.4, 8.5, 9.1, 9.2, 9.3, 9.4, 9.5, 10.1, 10.2, 10.3, 10.4, 10.5, 11.1, 11.2, 11.3, 11.4, 11.5, 12.1, 12.2, 12.3, 12.4, 12.5] 
from itertools import groupby  
print [map(int,str(max(list(cgen))).split('.')) for c,cgen in groupby(sorted(L),lambda x:int(x))] 

輸出:

[[2, 5], [3, 4], [4, 4], [5, 6], [6, 5], [7, 5], [8, 5], [9, 5], [10, 5], [11, 5], [12, 5]] 
相關問題