Python losing track of index location in for loop when my list has duplicate values - python-3.x

I'm trying to iterate over pairs of integers in a list. I'd like to return pairs where the sum equals some variable value.
This seems to be working just fine when the list of integers doesn't have repeat numbers. However, once I add repeat numbers to the list the loop seems to be getting confused about where it is. I'm guessing this based on my statements:
print(list.index(item))
print(list.index(item2))
Here is my code:
working_list = [1,2,3,4,5]
broken_list = [1,3,3,4,5]
def find_pairs(list, k):
pairs_list = []
for item in list:
for item2 in list:
print(list.index(item))
print(list.index(item2))
if list.index(item) < list.index(item2):
sum = item + item2;
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
### First parameter is the name is the list to check.
### Second parameter is the integer you're looking for each pair to sum to.
find_pairs(broken_list, 6)
working_list is fine. When I run broken_list looking for pairs which sum to 6, I'm getting back (1,5) but I should also get back (3,3) and I'm not.

You are trying to use list.index(item) < list.index(item2) to ensure that you do not double count the pairs. However, broken_list.index(3) returns 1 for both the first and second 3 in the list. I.e. the return value is not the actual index you want (unless the list only contains unique elements, like working_list). To get the actual index, use enumerate. The simplest implementation would be
def find_pairs(list, k):
pairs_list = []
for i, item in enumerate(list):
for j, item2 in enumerate(list):
if i < j:
sum = item + item2
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
For small lists this is fine, but we could be more efficient by only looping over the elements we want using slicing, hence eliminating the if statement:
def find_pairs(list, k):
pairs_list = []
for i, item in enumerate(list):
for item2 in list[i+1:]:
sum = item + item2
if sum == k:
pair = (item, item2)
pairs_list.append(pair)
return pairs_list
Note on variable names
Finally, I have to comment on your choice of variable names: list and sum are already defined by Python, and so it's bad style to use these as variable names. Furthermore, 'items' are commonly used to refer to a key-value pair of objects, and so I would refrain from using this name for a single value as well (I guess something like 'element' is more suitable).

Related

Recursive sum of a list in subgroups

I'm trying to write a function that gets a list of numbers and variable "v", this function should return a list all subgroups of the list that sums "v" without repeating
Example: if list = [2,3,5,6,8,9,1] and v = 11 it should return [[9,2], [8,3], [5,6], [2,3,5,1], [8,2,1], [6,3,2]]
Edit: the numbers in list are positives and v number isn't going to be much bigger than the sum in list
I've tried doing splits of the list and making it doubly linked list, and then counting the subgroups, but I don't really get to the answer.
This one to go through the list and then trying to extract the items, but I don't really know how to do it
def traverse(self, head):
if (head == None):
return
current_node = head
count = 1
while (current_node):
count += 1
current_node = current_node.next
return count

Check list for part of value and return whole value

I have a master list of ID numbers and another list of partial ID numbers. I need to check if the partial ID number is in the master list. If so, I need to return the whole ID number into a new list. What I have:
master_list = ['20000-K-A', '20000-K-B', '20000-K-C', '30000-R-X', '30000-R-V', '30000-R-F']
partial_list = [20000, 40000, 500000]
new_list =[]
for x in partial_list:
if x in master_list:
new_list.append(x)
print(new_list)
Now this only works if the partial ID number is EXACTLY what is in the master list. How do I return the value from the master list so that I can add it to the new list?
One option is to create a lookup dictionary first from master_list (note that the master_list is a list of strings while partial_list is a list of integers, so we need to cast the prefix to int):
d = {}
for item in master_list:
k, _ = item.split('-', maxsplit=1)
d.setdefault(int(k), []).append(item)
which looks like:
{20000: ['20000-K-A', '20000-K-B', '20000-K-C'],
30000: ['30000-R-X', '30000-R-V', '30000-R-F']}
Then iterate over partial_list to get the partially matching Ids:
new_list =[]
for x in partial_list:
new_list.extend(d.get(x, []))
Output:
['20000-K-A', '20000-K-B', '20000-K-C']

Two Sum function not working with recurring elements in list

I'm trying to complete "Two Sum", which goes as such:
Write a function that takes an array of numbers (integers for the tests) and a target number. It should find two different items in the array that, when added together, give the target value. The indices of these items should then be returned in a tuple like so: (index1, index2).
Efficiency of my code aside, this is what I have so far:
def two_sum(numbers, target):
for i in numbers:
for t in numbers:
if i + t == target:
if numbers.index(i) != numbers.index(t):
return (numbers.index(i), numbers.index(t))
return False
It works for inputs such as:
>>> two_sum([1,2,3,4,5,6,7,8,9,10], 11)
(0, 9)
But when I try a list of numbers that have recurring numbers that add up to the target, the code doesn't work:
>>> two_sum([2, 2], 4)
False
The code, for some reason that I cannot figure out, does not reach index [1] of the list, and thus returns False.
Why is that?
The list method index() always returns the first occurence of an item in a list, so numbers.index(i) != numbers.index(t) evaluates to 1 != 1 which is False.
You should use the builtin enumerate() to store the indices while looping over the list.
def two_sum(numbers, target):
for i, number_a in enumerate(numbers):
for j, number_b in enumerate(numbers):
if number_a + number_b == target and i != j:
return (i, j)
return False
'''
return will break the loop and come out of function, so first you need to complete the cycle, store the result in list as you cant write to tuple,
once your loop gets completed convert list to tuple and return
'''
def two_sum(numbers, target):
result = []
for i in numbers:
for t in numbers:
if (i + t == target) and (numbers.index(i) != numbers.index(t)):
result.append(i)
result.append(t)
if (len(result)> 0):
return tuple(result)
else:
return False
Your code looks fine except this part:
if numbers.index(i) != numbers.index(t):
return (numbers.index(i), numbers.index(t))
return False
Because the index method returns only the first occurrence of a value, i and t are always the same. It will always return false. The index of the value 2 is always 0 in the list even though there is another 2 at index 1.
Source: https://www.w3schools.com/python/ref_list_index.asp
What you want to do is this:
def two_sum(numbers, target):
i_index = 0
t_index = 0
for i in numbers:
for t in numbers:
if i + t == target:
if i_index != t_index:
return (i_index, t_index)
t_index +=1
i_index +=1
return False
This way the index is not associated with the value
def pairs_sum_to_target(list1, list2, target):
'''
This function is about a game: it accepts a target integer named target and
two lists of integers (list1 and list2).
Then this function should return all pairs of indices in the form [i,j]
where list1[i] + list[j] == target.
To summarize, the function returns the pairs of indices where the sum of
their values equals to target.
Important: in this game list1 and list2 will always have the same number of
elements and returns the pairs in that order.
'''
pairs = [] #make a list, which is empty in the beginning. But store the sum pairs == target value.
#loop for all indices in list1 while looping all the same indices in list2 and comparing if the sum == target variable.
for i, value1 in enumerate (list1):
for j, value2 in enumerate(list2):
if value1 + value2 == target: ## if the value of element at indice i + value of element at indice j == target, then append the pairs to list pairs []- in order.
pairs.append(i,j)
return pairs
Simple Input #1
"""This is one example of input for list1, list2, and target. In order to properly test this function"""
list1 = [1,-2,4,5,9]
list2 = [4,2,-4,-4,0]

How a Python code to store integer in list and then find the sum of integer stored in the List

List of integer value passed through input function and then stored in a list. After which performing the operation to find the sum of all the numbers in the list
lst = list( input("Enter the list of items :") )
sum_element = 0
for i in lst:
sum_element = sum_element+int(i)
print(sum_element)
Say you want to create a list with 8 elements. By writing list(8) you do not create a list with 8 elements, instead you create the list that has the number 8 as it's only element. So you just get [8].
list() is not a Constructor (like what you might expect from other languages) but rather a 'Converter'. And list('382') will convert this string to the following list: ['3','8','2'].
So to get the input list you might want to do something like this:
my_list = []
for i in range(int(input('Length: '))):
my_list.append(int(input(f'Element {i}: ')))
and then continue with your code for summation.
A more pythonic way would be
my_list = [int(input(f'Element {i}: '))
for i in range(int(input('Length: ')))]
For adding all the elements up you could use the inbuilt sum() function:
my_list_sum = sum(my_list)
lst=map(int,input("Enter the elements with space between them: ").split())
print(sum(lst))

Python3 - Combine Dictionaries with existing key value pairs

So... I know we can combine 2 dictionaries from python 3.5 like so:
z = {**x,**y} # x,y are 2 similar dictionaries, with nested entries
But in this method, any conflicting key,value pairs in 'x' is replaced with the ones in 'y'.
I want the conflicting key,value pairs to contain largest data present in x or y.
For example:
x = {1:'small_data',2:{1:'random laaaarge data',2:'random small data'}}
y = {1:'laaaaaarge_data',2:{1:'random small data',2:'random laaaarge data'}}
Now
z = {**x,**y}
# DATA in z should be {1:'laaaaaarge_data',2:{1:'random laaaarge data',2:'random laaaarge data'}}
NOTE: It should work for any arbitrary data that has a size.
Is this even possible? If so, what is the most pythonic way to do it.
Why not something like:
def merge_dicts(dict_list):
merged = {}
for sub_dict in dict_list:
for key, value in sub_dict.items():
if key in merged:
merged[key] = get_biggest(merged[key], value)
else:
merged[key] = value
return merged
def get_biggest(*items):
# function for comparing your 2 items based on your "size" requirements
return biggest

Resources