Check list for part of value and return whole value - python-3.x

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']

Related

How to subtract adjacent items in list with unknown length (python)?

Provided with a list of lists. Here's an example myList =[[70,83,90],[19,25,30]], return a list of lists which contains the difference between the elements. An example of the result would be[[13,7],[6,5]]. The absolute value of (70-83), (83-90), (19-25), and (25-30) is what is returned. I'm not sure how to iterate through the list to subtract adjacent elements without already knowing the length of the list. So far I have just separated the list of lists into two separate lists.
list_one = myList[0]
list_two = myList[1]
Please let me know what you would recommend, thank you!
A custom generator can return two adjacent items at a time from a sequence without knowing the length:
def two(sequence):
i = iter(sequence)
a = next(i)
for b in i:
yield a,b
a = b
original = [[70,83,90],[19,25,30]]
result = [[abs(a-b) for a,b in two(sequence)]
for sequence in original]
print(result)
[[13, 7], [6, 5]]
Well, for each list, you can simply get its number of elements like this:
res = []
for my_list in list_of_lists:
res.append([])
for i in range(len(my_list) - 1):
# Do some stuff
You can then add the results you want to res[-1].

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))

List Comprehension with "if" is not returning the same output as when I make a For Loop when counting the number of unique letters in a word

Can someone explain to me why there is a difference in output when using nested loops vs nested list comprehension?
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
def unique_english_letters (word) :
unique = []
for i in word:
if i not in unique:
unique.append(i)
return len(unique)
print(unique_english_letters("mississippi"))
# outputs 4 (my expected output)
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
def unique_english_letters (word) :
unique = []
unique = [i for i in word if i not in unique]
return len(unique)
print(unique_english_letters("mississippi"))
#outputs 11 (length of mississippi"
^ Output
In the second example, this:
unique = []
unique = [i for i in word if i not in unique]
is equivalent to:
unique = [i for i in word if i not in []]
unique is an empty list while the list comprehension is evaluated, and then unique is re-assigned the results.
To do what you want in simple terms, use a set which can only contain unique values, and use set intersection(& operator) to generate the set of letters contained in word:
letters = set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
def unique_english_letters(word):
return len(letters & set(word))
print(unique_english_letters("mississippi"))
# output: 4

Matching character lists of unequal length

I want to match two lists from which one list is smaller while other is a bigger one. If a match occurs between two lists then put the matching element in a new list at the same index instead of putting it another index. You can understand my question from the code given below:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist = []
smaller_list_len = min(len(list1),len(list2))
for ind in range(smaller_list_len):
elem2 = list1[ind]
elem1 = list2[ind][0:2]
if elem1 in list2:
matchlist.append(list1[ind])
Obtained output
>>> matchlist
['KNJ', 'NJK', 'JNJ']
Desired Output
>>> matchlist
['AFG', 'KNJ', 'JNJ', 'NJK']
Is there a way to get the desired output?
Use a nested loop iterating over the 3-char list. When an item in that list contains the current item in the 2-char list, append it and break out of the inner loop:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist = []
smaller_list_len = min(len(list1),len(list2))
for ind in range(smaller_list_len):
for item in list2:
if list1[ind] in item:
matchlist.append(item)
break
Given the question doesn't specify any constraints, in a more pythonic way, using a list comprehension:
list1=['AF','KN','JN','NJ']
list2=['KNJ','NJK','JNJ','INS','AFG']
matchlist=[e2 for e1 in list1 for e2 in list2 if e2.startswith(e1)]
produces
['AFG', 'KNJ', 'JNJ', 'NJK']

Python losing track of index location in for loop when my list has duplicate values

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).

Resources