让我说我有这样的事情:
08-22 12:33:10.833 13362-13362/com.my.blacky E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.my.blacky, PID: 13362
java.lang.ClassCastException: com.my.blacky.PrefsActivity cannot be cast to com.my.blacky.MainActivity
at com.gerpue.blacky.FragmentPrefs$2.onPreferenceClick(FragmentPrefs.java:62)
at android.preference.Preference.performClick(Preference.java:996)
at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:214)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1188)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3105)
at android.widget.AbsListView$3.run(AbsListView.java:4096)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5551)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
这给了我一个清单:
list(range(9:12))
但我希望它像:
[9,10,11]
将每个整数分成单个数字,无论如何在不牺牲太多性能的情况下实现这一目标?或者有没有办法首先生成这样的列表?
答案 0 :(得分:4)
最简单的方法是,
>>> [int(i) for i in range(9,12) for i in str(i)]
[9, 1, 0, 1, 1]
>>>
答案 1 :(得分:4)
您可以有效地构建最终结果,而无需使用itertools.chain.from_iterable
构建一个大型和/或小型中间字符串。
Sub test()
Dim wb1 As Excel.Workbook
Set wb1 = Workbooks("XXX.XLSM") ' from here, use wb1 to refer to fua.xlsm
Dim wb2 As Excel.Workbook ' ditto for wb2
Set wb2 = Workbooks.Open("C:\Users\Ha.csv")
Dim sht1 As Worksheet ' ditto for sht1
Set sht1 = wb1.Sheets("Sheet1")
Dim sht2 As Worksheet
Set sht2 = wb2.Sheets("Ha")
If Application.WorksheetFunction.CountA(sht1.Cells) <> 0 Then
LastRow = sht1.Cells.Find( _
What:="*", _
After:=sht1.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).row
Else
LastRow = 1
End If
sht1.ListObjects.Add(xlSrcRange, sht1.Range("A:I"), xlYes).Name = "Table1"
sht1.ListObjects("Table1").Range.AutoFilter _
Field:=9, _
Criteria1:=">=-1000000000000", _
Operator:=xlAnd, _
Criteria2:="<=1000000000000000"
Application.DisplayAlerts = False ' not sure if needed
sht1.Range("A:I").SpecialCells(xlCellTypeVisible).Copy
On Error Resume Next
sht2.Range("A:I").Copy Columns(last_col + 1).PasteSpecial
On Error Resume Next
Application.DisplayAlerts = True ' not sure if needed
wb2.Save ' already C:\Users\Ha.csv
wb2.Close
End Sub
In [18]: list(map(int, chain.from_iterable(map(str, range(9, 12)))))
Out[18]: [9, 1, 0, 1, 1]
计时与输入相关。 itertools 版本还有效地使用内存,但如果与In [12]: %%timeit
...: list(map(int, chain.from_iterable(map(str, range(9, 20)))))
...:
100000 loops, best of 3: 8.19 µs per loop
In [13]: %%timeit
...: [int(i) for i in ''.join(map(str, range(9, 20)))]
...:
100000 loops, best of 3: 9.15 µs per loop
In [14]: %%timeit
...: [int(x) for i in range(9, 20) for x in str(i)]
...:
100000 loops, best of 3: 9.92 µs per loop
一起使用,它比str.join
版本略慢:
list(map(int, ...))
答案 2 :(得分:3)
将整数转换为字符串,然后将split()
转换为字符串并将数字重新转换回整数。
li = range(9,12)
digitlist = [int(d) for number in li for d in str(number)]
输出:
[9,1,0,1,1]
答案 3 :(得分:1)
我已经调查了我能做多少这方面的表现。我写的第一个函数是naive_single_digits
,它使用str
方法,具有非常高效的列表理解。
def naive_single_digits(l):
return [int(c) for n in l
for c in str(n)]
如您所见,这种方法有效:
In [2]: naive_single_digits(range(9, 15))
Out[2]: [9, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4]
但是,我认为始终为列表中的每个项目构建一个str
对象肯定是必要的 - 我们实际需要的只是对数字的基本转换。出于懒惰,我从here复制了这个函数。我通过将其指定为10来优化它。
def base10(n):
if n == 0:
return [0]
digits = []
while n:
digits.append(n % 10)
n //= 10
return digits[::-1]
使用这个,我做了
def arithmetic_single_digits(l):
return [i for n in l
for i in base10(n)]
也表现正确:
In [3]: arithmetic_single_digits(range(9, 15))
Out[3]: [9, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4]
现在来吧。我还针对另一个答案进行了测试(完全披露:我在Python2中对其进行了一些修改,但这不会影响性能)
In [11]: %timeit -n 10 naive_single_digits(range(100000))
10 loops, best of 3: 173 ms per loop
In [10]: %timeit -n 10 list(map(int, itertools.chain(*map(str, range(100000)))))
10 loops, best of 3: 154 ms per loop
In [12]: %timeit arithmetic_single_digits(range(100000))
10 loops, best of 3: 93.3 ms per loop
正如您所看到的,arithmetic_single_digits
实际上有点快,虽然这是以更多代码为代价而且可能不太清晰。我已经对可笑的大输入进行了测试,因此您可以看到性能上的差异 - 在任何合理的范围内,这里的每个答案都会非常快。请注意,python的整数运算实际上可能相对较慢,因为它不使用原始整数类型。如果要在C中实现,我怀疑我的方法会更快一些。
将此与viblo的回答相比较,使用(纯)Python 3(令我遗憾的是我还没有为python 3安装ipython):
print(timeit.timeit("digits(range(1, 100000))", number=10, globals=globals()))
print(timeit.timeit("arithmetic_single_digits(range(1, 100000))", number=10, globals=globals()))
输出结果为:
3.5284318959747907
0.806847038998967
我的方法相当快,大概是因为我纯粹使用整数运算。
答案 4 :(得分:1)
编写算术解决方案的另一种方法。与Izaak van Dongens解决方案相比,这不会使用while循环,但会预先计算列表理解/循环中需要多少次迭代。
import itertools, math
def digits(ns):
return list(itertools.chain.from_iterable(
[
[
(abs(n) - (abs(n) // 10 **x)*10**x ) // 10**(x-1)
for x
in range(1+math.floor(math.log10(abs(n) if n!=0 else 1)), 0, -1)]
for n in ns
]
))
digits([-11,-10,-9,0,9,10,11])
答案 5 :(得分:0)
将其转换为字符串然后返回列表:)
lambda x: list(''.join(str(e) for e in x))
答案 6 :(得分:0)
您也可以使用地图功能
a=range(9,12)
res = []
b=[map(int, str(i)) for i in a]
for i in b:
res.extend(i)
print(res)
答案 7 :(得分:0)
这是我的表现:
ls = range(9,12)
lsNew = []
length = len(ls)
for i in range(length):
item = ls[i]
string = str(item)
if len(string) > 1:
split = list(string)
lsNew = lsNew + split
else:
lsNew.append(item)
ls = lsNew
print(ls)
答案 8 :(得分:0)
def breakall(L):
if L == []:
return []
elif L[0] < 10:
return [L[0]] + breakall(L[1:])
else:
return breakall([L[0]//10]) + [L[0] % 10] + breakall(L[1:])
print(breakall([9,10,12]))
-->
[9, 1, 0, 1, 2]