拥有以下代码:
import sys
ints = [1,2,3,4,5,6,8,9,10,11,14,34,14,35,16,18,39,10,29,30,14,26,64,27,48,65]
ints.sort()
ints = list(set(ints))
c = {}
for i,v in enumerate(ints):
if i+1 >= len(ints):
continue
if ints[i+1] == v + 1 or ints[i-1] == v - 1:
if len(c) == 0:
c[v] = [v]
c[v].append(ints[i+1])
else:
added=False
for x,e in c.items():
last = e[-1]
if v in e:
added=True
break
if v - last == 1:
c[x].append(v)
added=True
if added==False:
c[v] = [v]
else:
if v not in c:
c[v] = [v]
print('input ', ints)
print('output ', c))
目标:
给定一个整数列表,创建一个包含连续整数的字典,以减少列表的总长度。
以下是我当前解决方案的输出:
input [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 16, 18, 26, 27, 29, 30, 34, 35, 39, 48, 64, 65]
output {1: [1, 2, 3, 4, 5, 6], 8: [8, 9, 10, 11], 14: [14], 16: [16], 18: [18], 26: [26, 27], 29: [29, 30], 34: [34, 35], 39: [39], 48: [48], 64: [64]}
条件/约束:
3
时,不要创建列表3,4
,而是将3
附加到现有列表[1,2]
< / LI>
我当前的迭代工作正常,但由于for x,e in c.items()
现有列表检查,列表越大,指数越小。
如何在实现相同结果的同时加快速度?
新解决方案(使用19,000个整数的输入列表从13秒到0.03秒):
c = {}
i = 0
last_list = None
while i < len(ints):
cur = ints[i]
if last_list is None:
c[cur] = [cur]
last_list = c[cur]
else:
if last_list[-1] == cur-1:
last_list.append(cur)
else:
c[cur] = [cur]
last_list = c[cur]
i += 1
答案 0 :(得分:3)
由于您有连续数字列表,我建议您使用range
个对象而不是list
s:
d, head = {}, None
for x in l:
if head is None or x != d[head].stop:
head = x
d[head] = range(head, x+1)
答案 1 :(得分:2)
如果您使用@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_question);
add_question = findViewById(R.id.addquestion);
question_EditText = findViewById(R.id.question_add);
add_question.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
final String question = question_EditText.getText().toString();
Log.d("finds","question1:"+question);
if (question.length()==0)
{
new AlertDialog.Builder(AddQuestionActivity.this)
.setTitle(R.string.add_error)
.setMessage(R.string.add_blank)
.setPositiveButton(R.string.ok, null)
.setNeutralButton(R.string.cancel, null)
.show();
}
}
});
}
循环并且只是跟踪当前列表,那么解决方案很简单。当你找到差距时,不要忘记制作新的清单:
for
答案 2 :(得分:1)
有一个很棒的名为more_itertools
的库,它有一个名为consecutive_groups()
的方法:
import more_itertools as mit
x = [1,2,3,4,5,6,8,9,10,11,14,34,14,35,16,18,39,10,29,30,14,26,64,27,48,65]
x = [list(j) for j in mit.consecutive_groups(sorted(list(set(x))))]
# [[1, 2, 3, 4, 5, 6], [8, 9, 10, 11], [14], [16], [18], [26, 27], [29, 30], [34, 35], [39], [48], [64, 65]]
dct_x = {i[0]: i for i in x}
print(dct_x)
输出:
{1: [1, 2, 3, 4, 5, 6], 8: [8, 9, 10, 11], 14: [14], 16: [16], 18: [18], 26: [26, 27], 29: [29, 30], 34: [34, 35], 39: [39], 48: [48], 64: [64, 65]}
还有一条评论,您希望在转换为集合之后进行排序,因为集合是无序的。
答案 3 :(得分:0)
可以在O(n)
(线性)复杂性中解决此任务。保持简单:
integers = [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 16, 18, 26, 27, 29, 30, 34, 35, 39, 48, 64, 65]
helper = []
counter = 0
while counter < len(integers):
if not helper or helper[-1] + 1 != integers[counter]:
print('gap found', integers[counter]) # do your logic
helper.append(integers[counter])
counter += 1
上述算法假定输入列表已经排序。它给了我们巨大的优势。同时,在运行此算法之前,可以明确地对整数列表进行排序。然后,解决方案的总复杂性将是:O(n * log n) + O(n)
,这是有效的O(n * log n)
。 O(n * log n)
是排序过程的复杂性。
我建议记住这个非常有用的技巧,在接近任务以便将来使用之前使用排序。
答案 4 :(得分:0)
这是一个简单的实现,使用列表切片实现您的目标:
integers = [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 16, 18, 26, 27, 29, 30, 34, 35, 39, 48, 64, 65]
for i, integer in enumerate(integers):
if i == 0:
out_dict = {}
start = 0
else:
if integer != prev_integer + 1:
out_dict[integers[start]] = integers[start:i]
start = i
if i == len(integers) - 1:
out_dict[integers[start]] = integers[start:]
prev_integer = integer
>>>out_dict = {1: [1, 2, 3, 4, 5, 6], 8: [8, 9, 10, 11], 14: [14], 16: [16], 18: [18], 26: [26, 27], 29: [29, 30], 34: [34, 35], 39: [39], 48: [48], 64: [64]}
注意:字典可能不会按升序排序,因为dict
类型没有排序。
答案 5 :(得分:0)
您可以尝试使用itertools,但我想尝试递归:
input_dta=[1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 14, 16, 18, 26, 27, 29, 30, 34, 35, 39, 48, 64, 65]
final_=[]
def consecutives(data):
sub_final=[]
if not data:
return 0
else:
for i,j in enumerate(data):
try:
if abs(data[i]-data[i+1])==1:
sub_final.extend([data[i],data[i+1]])
else:
if sub_final:
final_.append(set(sub_final))
return consecutives(data[i+1:])
except IndexError:
pass
final_.append(set(sub_final))
consecutives(input_dta)
print(final_)
输出:
[{1, 2, 3, 4, 5, 6}, {8, 9, 10, 11}, {26, 27}, {29, 30}, {34, 35}, {64, 65}]