Я столкнулся с этой проблемой, но мне было нужно решение, в котором сохранялись имена каждого элемента. Решение, которое я придумал, должно также работать, когда вспомогательные списки не имеют одинаковой длины.
invertList = function(l){
elemnames = NULL
for (i in seq_along(l)){
elemnames = c(elemnames, names(l[[i]]))
}
elemnames = unique(elemnames)
res = list()
for (i in seq_along(elemnames)){
res[[elemnames[i]]] = list()
for (j in seq_along(l)){
if(exists(elemnames[i], l[[j]], inherits = F)){
res[[i]][[names(l)[j]]] = l[[names(l)[j]]][[elemnames[i]]]
}
}
}
res
}
Ваша проблема в использовании eval
. Если он не может проанализировать строку как переменную, он должен завершиться ошибкой, но в вашем случае у вас уже есть t
, плавающая в пространстве имен. t
сохраняет свою старую идентичность, скажем, int, но затем вы пытаетесь добавить a
(строку) к числу.
Этот код должен работать:
sum,sum_i,c=0,0,0
sum_f=0.0
print("Enter q/Q to stop entering numbers.")
while True:
a=input("Enter number: ")
try:
t = int(a)
sum_i=sum_i+int(a)
c=c+1
print(type(t))
continue
except ValueError:
pass
try:
t = float(a)
sum_f=sum_f+int(a)
c=c+1
print(type(t))
continue
except ValueError:
pass
try:
if (a=='q'or a=='Q'):
break
else:
print("Invalid data entered. Please enter a number to add or q/Q to quit. ")
continue
except ValueError:
pass
sum= sum_i+ sum_f
print("You have entered ",c," numbers and their sum is: ",sum)
две вещи: во-первых, чтобы проверить тип чего-то более питонского для использования
isinstance(t, int)
, но во-вторых, когда ваш код не работает.
Если вы оцениваете литерал, вы, скорее всего, получите ошибку имени, поскольку переменная нигде не определена. Однако, если вы введете «с», например, вы получите что-то странное полностью. Поскольку переменная c определена, вы не получите ошибку имени, но она все равно потерпит неудачу при приведении литерала 'c' к int.
Вы можете использовать регулярное выражение, чтобы проверить, является ли ввод числом или нет
, например, так.
if re.match('(\d+(\.\d+)?)', a):
try:
t = eval(a)
print(type(t))
except (NameError, ValueError):
pass
elif a == 'q' or a == 'Q':
break
else:
continue
if isinstance(t, int):
sum_i = sum_i + int(a)
c = c + 1
elif isinstance(t, float):
sum_f = sum_f + float(a)
c = c + 1
else:
print("Invalid data entered. Please enter a number to add or q/Q to quit. ")
Вот рефакторинг с использованием вложенного try/except
, который решает проблему несколько лаконичнее и питоннее.
#!/usr/bin/env python3
nums = list()
while True:
# Usability tweak: Trim surrounding whitespace
a = input("Enter number: ").strip()
try:
t = int(a)
except ValueError:
try:
t = float(a)
except ValueError:
if a in ('q', 'Q'):
break
print("Invalid data entered. Please enter a number or q/Q to quit.")
continue
nums.append(t)
print("You have entered {0} numbers and their sum is {1}".format(
len(nums), sum(nums)))