Python error "cannot unpack non-iterable int object" [duplicate] - python

This question already has answers here:
How to split a list into pairs in all possible ways
(14 answers)
Closed last year.
I want to get the indexes of the elements in the list which add up to the sum.
numbers = [10,2,3,5,8,200]
sum = 12
for i,v in numbers:
if i+v == sum:
print(numbers[i]), print(numbers[v])
else:
print("other")
But I get this error:
Traceback (most recent call last):
File "C:\User\User\PycharmProjects\training\tests.py", line 9, in <module>
for i,v in numere:
TypeError: cannot unpack non-iterable int object

You can't expect to get indices from a list item like this. Use enumerate() to accomplish it instead.
for i, v in enumerate(numbers):

This is the infamous Two Sum problem on LeetCode, and As LeetCode states :
We can do it in one-pass. While we are iterating and inserting elements into the hash table, we also look back to check if current element's complement already exists in the hash table. If it exists, we have found a solution and return the indices immediately.
def twoSum(nums: List[int], sum: int) -> List[int]:
hashmap = {}
for i in range(len(nums)):
complement = sum - nums[i]
if complement in hashmap:
return [i, hashmap[complement]]
hashmap[nums[i]] = i
x = twoSum(nums=numbers, sum=sum)
print(x)

Related

how to write a recursive function that sums the integers in a tree?

Write a recursive function TreeSum(T) to add up all the integers in a tree. My test case is
TreeSum(set)
48
where
set=[[[[2,1],[3,7]],[1,2]],[[0,6],[[[3,2],[1,1]],[9,10]]]]
This is the code I have so far:
def TreeSum(T):
if len(T)==0:
return 0
else:
return T[0] + TreeSum(T[1:])
I am getting an error from the return line ("can only concatenate list (not "int") to list"). How can I fix this?
Error:
----> 5 return T[0] + TreeSum(T[1:])
6
7 TreeSum(maple)
TypeError: can only concatenate list (not "int") to list
#j1-lee had the correct approach, but this is limited in terms of span of the sublists (silently ignoring the items with a position > 1, or failing if one of the first two elements is an integer). You need to apply the recursive function on all sub-elements. One way is to use map
NB. I slightly changed the input to add two more elements to the first sublist
tree = [[[[2,1],1,[3,7],[1]],[1,2]],[[0,6],[[[3,2],[1,1]],[9,10]]]]
def treesum(x):
if not isinstance(x, list):
return x
return sum(map(treesum, x))
print(treesum(tree))
Output: 50

List comprehension works but not generator expression [duplicate]

This question already has answers here:
A safe max() function for empty lists
(7 answers)
Closed 1 year ago.
I am doing this problem:
Given an array of integers arr, a lucky integer is an integer which has a frequency in the array equal to its value.
Return a lucky integer in the array. If there are multiple lucky integers return the largest of them. If there is no lucky integer return -1.
I am using this code, which works and passed all tests:
class Solution:
def findLucky(self, arr: List[int]) -> int:
values = [n for n in arr if n if arr.count(n) == n]
return max(values) if values else -1
However, when I try to change the list comprehension to a generator expression like so:
class Solution:
def findLucky(self, arr: List[int]) -> int:
values = (n for n in arr if n if arr.count(n) == n)
return max(values) if values else -1
I get this error:
Traceback (most recent call last):
File "...", line 10, in <module>
print(Solution().findLucky([2, 3, 4]))
File "...", line 7, in findLucky
return max(values) if values else -1
ValueError: max() arg is an empty sequence
Why does a list comprehension work whereas a generator expression fails?
I've tried converting the generator expression to a list in the comprehension, but that won't work because then the generator is exhuased.
Every generator is true, so you always call max(values) even if the generator is "empty". The right way to do it is to tell max what to do then:
return max(values, default=-1)

Python for loop range addition [duplicate]

This question already has answers here:
Python:How to make the sum of the values of a while loop store into a variable?
(4 answers)
Closed 4 months ago.
Hello (beginner here),
I am trying to write a script that prints the sum of every even numbers in the range [0; 100].
However, I am getting a "TypeError: 'int' object is not iterable".
This is my code:
for i in range(0, 101):
total = 0
if i % 2 == 0:
total = sum(i)
print(total)
My error message:
Traceback (most recent call last):
File "", line 4, in
TypeError: 'int' object is not iterable
I've searched this website and Google to understand what I'm doing wrong, but I cant seem to grasp an answer to my specific code.
Any help would be greatly appreciated.
The problem is with the sum function it is not used in that manner. If you give 1 argument then it should be a list then you can use .append() function but in your use-case you can simply use + i.e., addition.
total = 0
for i in range(0, 101):
if i % 2 == 0:
total += i
print(total)
The sum() function can only sum up an iterable (list, dict, etc.). In your loop, your variable i is seen as a solid number, not a list. If you want to sum up every even number, you need to add i to a list:
list1 = []
for i in range(0, 101):
if i % 2 == 0:
list1.append(i)
total = sum(list1)
print(total)
Here is a better version, if you do not want the output after every single addition:
print(sum([i for i in range(0,101, 2)]))
the answer to your question using sum function can simply be
for i in range(0, 101, 2):
total = 0
total = sum(i, total)
print(total)
Learn more about Python loops here!
Learn Python fundamentals here!

Index out of range when traversing a single list using a nested for loop [duplicate]

This question already has answers here:
Accessing the index in 'for' loops
(26 answers)
Closed 2 years ago.
I am working through a challenge and I'm trying to use a nested for loop to solve it. The challenge asks in a given array of integers nums and an integer k, determine whether there are two distinct indices i and j in the array where nums[i] = nums[j] and the absolute difference between i and j is less than or equal to k.
This is my attempt:
def containsCloseNums(nums, k):
for i in nums:
for j in nums:
if (nums[i] == nums[j]) and abs(i-k) <= k:
return True
else:
return False
But this is the error I'm getting:
Traceback (most recent call last):
main.py3 in the pre-written template, in getUserOutputs
userOutput = _rundyxlc(testInputs[i])
main.py3 in the pre-written template, in _rundyxlc
return containsCloseNums(*_fArgs_zeutcbsrcmec)
main.py3 in the pre-written template, in containsCloseNums
if (nums[i] == nums[j]) and abs(i-j) <= k:
IndexError: list index out of range
I don't see a reason for why I'd be out of index because I'm not incrementing beyond the list's length.
I appreciate all help but since this is a challenge, it is more beneficial for me to know why my logic didn't work as opposed to just spitting out an answer.
In your code
for i in nums:
"i" is item in this list "nums".
You should change to:
for index_i, value_i in enumerate(nums):
Then "index_i" is the index of item while value_i is the value of the item in list "nums"
By the way I think it should be:
def containsCloseNums(nums, k):
for i_index, i_value in enumerate(nums):
for j_index, j_value in enumerate(nums):
if (i_value == j_value) and abs(i_index-j_index) <= k:
return True
else:
return False
For-loop traverses values in list, not indices.
L = [1, 5, 4]
for i in L:
print(i)
You will see:
1
5
4
There is enumerate function to get indices. It forms tuples of (indice, value) for each value in list:
for i, val in enumerate(L):
print(i, val)
output:
0, 1
1, 5
3, 4
Also, your solution has O(n^2) complexity which is not perfect for your task. Think if you coud use sets, dicts, or maybe make some use of sorting your list.
You should change your for loops to:
for i in range(len(nums)):
for j in range(len(nums)):
You are yielding elements instead of indices. There is an element in nums which is greater than the length of nums, that's why the error is throwed.
The problem in your code is that when you do
for i in nums
than i is an item from nums and not an index
so for comparing you can simply do
if i == j
but as you have to use indexes as well to compare with k you can do
for key, value in enumerate(nums):
where key will be the index and value will be the corresponding item.
Right now this code nums[i] and nums[j] will try accessing the ith and jth element in the list. This is what causes the error. if nums = [10, 20] and nums[10] and nums[20] do not exist.
What you want to do is to access the index of each element in the list and use that in the for loop. To access the index you can use enumerate.
I have also edited your code so that it works now.
def containsCloseNums(nums, k):
for idxi, i in enumerate(nums):
for idxj, j in enumerate(nums):
if (nums[idxi] == nums[idxj]) and abs(i-k) <= k:
return True
else:
return False

Puzzle returns unsupported TypeError

I'm trying to write a python A*. I believe that my traversal and my heuristic are right but I get an error that I don't understand. I can't change the main test function but the rest can be manipulated.
The code for the puzzle is:
def pop(self):
pairs = list()
for item in self.frontier:
pairs.append((self.priority[item], item))
(p, item) = min(pairs)
self.frontier.remove(item)
return item
The error that I get when I run the code reads:
125
487
36
Traceback (most recent call last):
File "C:/Users/mchri/Desktop/AI/Homework/eightpuzzle/eightpuzzle.py", line 129, in <module>
main()
File "C:/Users/mchri/Desktop/AI/Homework/eightpuzzle/eightpuzzle.py", line 119, in main
path = agent.astar(puzzle, goal)
File "C:/Users/mchri/Desktop/AI/Homework/eightpuzzle/eightpuzzle.py", line 86, in astar
parent = self.pop()
File "C:/Users/mchri/Desktop/AI/Homework/eightpuzzle/eightpuzzle.py", line 106, in pop
(p, item) = min(pairs)
TypeError: '<' not supported between instances of 'Puzzle' and 'Puzzle'
The puzzle almost solves itself but begins to misplace the numbers and I don't understand how that's a result of the unsupported < instance.
You are using min() to get the lowest priority value out of a list of tuples, with priority values and puzzles. The way min() works, is that it compares both values in the tuple, so it will first sort by priority value, then by Puzzle. There is, however no < operator for Puzzle, because one puzzle is not less than the other.
I assume you just want to sort by priority value, which can be done like this:
(p, item) = min(pairs, key=lambda t: t[0])
If you do want to sort by both priority value and puzzle, you'll need to implement a lt an eq operator for Puzzle (See Brian Joseph's answer)
Because, your code doesn't know which puzzle is "greater" than or "less" than the other. You need to define some -- if not all -- of these magic/dunder methods to tell python how to compare them:
__lt__(a, b)
__le__(a, b)
__eq__(a, b) # <-- You already have this
__ne__(a, b) # <-- You already have this
__ge__(a, b)
__gt__(a, b)
read more here: "rich comparison" methods.
So I added a print statement, like so:
for item in self.frontier:
pairs.append((self.priority[item], item))
print(pairs) # <- My addition
(p, item) = min(pairs)
And your code fails when your pairs list looks like this:
[
(10, <__main__.Puzzle object at 0x000002019C4C7278>),
(10, <__main__.Puzzle object at 0x000002019C4C7358>),
(12, <__main__.Puzzle object at 0x000002019C4C72B0>)
]
The way that min works on tuples is this: it compares the first item in each tuple. If those are equal, then it compares the next item. And so on and so forth until it finds an item pair that "breaks the tie", so to speak.
For the above pairs list, there are two tuples with a first element of 10; since these are equal, the min function then tries to compare the two Puzzle objects. But Puzzle objects don't know how to be compared! So your code throws an error saying so.
But really, you just want to find the tuple with the smallest p value, right? So you can replace (p, item) = min(pairs) with this:
(p, item) = min(pairs, key=lambda t: t[0])

Categories