我试图编写一个函数来测试列表是否具有连续数字但是具有非常奇怪的捕获。问题在于" a"可以用作任何整数的替代,但列表中至少有2个元素必须是数字。元素> = 1(如果不是" a")并且是整数。可以假设输入是这种形式,因此不需要检查它。 我对编码很陌生,所以我实际上更喜欢在一个衬垫上使用循环,因为我还不熟悉一个衬垫的使用。
例如:
>>>check_consecutive([1,2,"a","a",5,6,7,"a"])
True
>>>check_consecutive(["a","a","a","a",9,10])
True
>>>check_consecutive(["a","a","a","a",5])
False #Need at least 2 elements to be numbers
>>>check_consecutive([3,4,5,"a",6,7])
False
>>>check_consecutive(["a","a","a","a","a","a",2,3])
False
我试图做的事情:
def check_consecutive(lst):
count = 0
for i in range(len(lst)-1):
if lst[i] == "a" or lst[i+1] == "a":
count +=1
elif lst[i+1] - lst[i] == 1:
count +=1
if count == len(lst)-1:
return True
return False
这不起作用,因为它没有考虑" a"的值。我不确定该怎么做。提前感谢您的帮助。
答案 0 :(得分:3)
尝试以下方法。它适用于所有测试用例,并且我将单行保持在最低限度:
def check_consecutive(lst):
# Check for the number of non-"a" entries in the list:
if len([x for x in lst if x != "a"]) < 2:
return False
# Get the first non-a value (ASSUMPTION: this is a number)
first_number = next((e for e in lst if e != "a"), None)
# Find the index of the first number
first_index = lst.index(first_number)
# Find the difference between the first number and its index
diff = first_number - first_index
# Based on the final example - false if negative values would be used:
if diff < 0:
return False
# Create a new list - replace a's with their index plus the difference we found
# If the list is consecutive, this difference will be consistent for all values
all_numbers = []
for i, x in enumerate(lst):
if x == "a":
all_numbers.append(i + diff)
else:
all_numbers.append(x)
# Check if the values are now consecutive or not!
if all(all_numbers[i+1] == all_numbers[i] + 1 for i in range(len(all_numbers) - 1)):
return True
else:
return False
print check_consecutive([1,2,"a","a",5,6,7,"a"])
#True
print check_consecutive(["a","a","a","a",9,10])
#True
print check_consecutive(["a","a","a","a",5])
#False #Need at least 2 elements to be numbers
print check_consecutive([3,4,5,"a",6,7])
#False
print check_consecutive(["a","a","a","a","a","a",2,3])
#False
如果您想了解一些单行工作的方式,可以按如下方式略微降低功能:
def check_consecutive(lst):
# Check for the number of non-"a" entries in the list:
if len([x for x in lst if x != "a"]) < 2:
return False
# Get the first non-a value (ASSUMPTION: this is a number)
first_number = next((e for e in lst if e != "a"), None)
# Find the index of the first number
first_index = lst.index(first_number)
# Find the difference between the first number and its index
diff = first_number - first_index
# Based on the final example - false if negative values would be used:
if diff < 0:
return False
if all(x == "a" or x == i + diff for i, x in enumerate(lst)):
return True
else:
return False
答案 1 :(得分:1)
这里有一个有效的解决方案。我知道你说你不想要列表推导(我用for
循环编辑它所以你可以理解):
def check_consecutive(a):
b = [(next(y for y in a if y!='a')-a.count('a') if a[0] == 'a' else a[0])+i if x=='a' else x for i, x in enumerate(a)]
return len(a) - a.count('a') >= 2 and b[0] >= 0 and range(b[0],b[-1]+1) == b
列表理解可以转化为:
for i,x in enumerate(a):
if x == 'a':
if a[0] == 'a':
# |---> Gets first integer from list
new_lst.append(next(x for x in a if x != 'a') - a.count('a'))
else:
new_lst.append(a[0]+i)
else:
new_lst.append(x)
答案 2 :(得分:1)
这不是那么好的解决方案。但我像这样向后试过这个名单 -
def check_consecutive(lst):
last = 0
number_count = len(lst) - lst.count('a')
# Check count of numbers and return if less than 2
if number_count < 2:
return False
for i in reversed(range(len(lst))):
# last 0 means no numbers encountered yet
if not last:
last = lst[i] if lst[i] != "a" else 0
continue
else:
# If current element is number check consecutive property
if lst[i] != "a" and last - lst[i] != 1:
return False
# Recalculate last
last -= 1
# If last falls below permissible range, return
if last < 1:
return False
# If all condition satisfied, it is a hit. Whew!!!
return True
print check_consecutive([1,2,"a","a",5,6,7,"a"])
print check_consecutive(["a","a","a","a",9,10])
print check_consecutive(["a","a","a","a",5])
print check_consecutive([3,4,5,"a",6,7])
print check_consecutive(["a","a","a","a","a","a",2,3])
答案 3 :(得分:1)
它适用于您的示例(py 2.7):
def check_consecutive(lst):
# what could be the list
cond = [0,1]
n_sum = False
for x in lst:
if not(cond[1]) and x!= 'a':
n_sum = True;
if (cond[0] - x) != (lst.index(cond[0]) - lst.index(x)):
return False
elif x <= lst.index(x):
return False
if x!='a' and cond[1]:
cond[0] = x;
cond[1] = 0;
print cond
return n_sum
答案 4 :(得分:1)
所有测试用例都假设序列以实际数字(或两者)开头或结尾。假设这是真的,我们可以在O(n)时间和O(1)空间中提出非常简单的显式解决方案。
def check_consecutive(seq):
PLACEHOLDER = 'a'
# O(n) check for preconditions
if sum(obj != PLACEHOLDER for obj in seq) < 2:
return False
if isinstance(seq[0], int):
# first element known, incrementing
incrementing = True
delta = 1
else:
# last element known, decrementing
incrementing = False
delta = -1
# iterate from first or last element
iterator = iter(seq) if incrementing else reversed(seq)
# consume first value
previous_item = next(iterator)
# check if our assumption is correct
assert previous_item != PLACEHOLDER
# O(n) check for valid sequence
for item in iterator:
# figure out expected placeholder value
if item == PLACEHOLDER:
item = previous_item + delta
# check if next value matches requirements of valid solution
if item <= 0 or item != (previous_item + delta):
return False
previous_item = item
return True
assert check_consecutive([1,2,"a","a",5,6,7,"a"]) is True
assert check_consecutive(["a","a","a","a",9,10]) is True
assert check_consecutive(["a","a","a","a",5]) is False
assert check_consecutive([3,4,5,"a",6,7]) is False
assert check_consecutive(["a","a","a","a","a","a",2,3]) is False
答案 5 :(得分:1)
所有其他答案可能都有效,但我尽量保持简单,直截了当,希望它有所帮助:)代码应该是不言自明的。
def check_consecutive(input_list):
# First find the first element that is not equal to a to figure out the start of the sequence
start_seq = None
for i, el in enumerate(input_list):
if el != 'a':
# Now we know the number the sequence should start with.
# For example the first 2 elements are a, and the first "non-a" element is 5
# Then the loop breaks when el = 5, and i = 2, meaning the start should be 3
start_seq = el - i
break
# If the whole list exists of a's, then start will still be None and the function should return false
if start_seq is None:
return False
if start_seq < 1:
return False
# Now we can loop over the list, keep replacing a's by what they should be
# Create some values for bookkeeping
num_n = 0
old_value = start_seq - 1
for el in input_list:
if el != 'a':
num_n += 1
if el != (old_value + 1):
return False
# increment old value
old_value += 1
if num_n < 2:
return False
return True