how to match items between 2 different lists - python

I have 2 different lists:
['2', '1']
['equals', 'x']
I want to match the items so 2 = "equals" and 1 = "x" in order to recreate the original sentence "x equals x", also i have a third list which is:
['1', '2', '1']
I need the third list to recreate the original sentence since it has all the positions, to do this I thought of making the numbers equal to the words such as 1 = "x" and printing the list of numbers in order to have the full sentence. The problem is i do not know how to make the numbers equal to the words. Thanks for the help in advance

A dictionary might be what you need here which maps keys to values. You can create a dictionary from the first two lists by zipping them. And with this dictionary, it should be fairly straight forward to map any list of numbers to words:
mapping = dict(zip(['2', '1'], ['equals', 'x']))
mapping
# {'1': 'x', '2': 'equals'}
[mapping.get(num) for num in ['1', '2', '1']]
# ['x', 'equals', 'x']
To make the list a sentence, use join method:
" ".join(mapping.get(num) for num in ['1', '2', '1'])
# 'x equals x'

Related

Code works only sometimes for removing odd or even index items

Question :​ Write a Python program to remove the characters which have odd or even index
values of a given string.
I tried to make a copy of the list by deep copy .
I ran a loop from first list and checked for even then used pop method on second list to remove that specific index from the second list .
This code works for some inputs , I think mostly for those which doesn't have any repeated characters and doesn't work for others.
Code
#!/usr/bin/python3
import copy
list1 = input("Enter a string ")
list1 = list(list1)
list2 = copy.deepcopy(list1)
for i in list1:
if list1.index(i)%2 != 0:
list2.pop(list2.index(i))
print(list2)
The outputs for some samples are :
123456789 -> ['1', '3', '5', '7', '9'], qwertyuiop -> ['q', 'e', 't', 'u', 'o'], saurav -> ['s', 'u'], 11112222333344445555 -> ['1', '1', '1', '1', '2', '2', '2', '2', '3', '3', '3', '3', '4', '4', '4', '4', '5', '5', '5', '5']
Read the documentation for index. It returns the index of the first occurrence of the given value. A simple print inside the loop will show you what's going on, in appropriate detail. This is a basic debugging skill you need to learn for programming in any language.
import copy
list1 = input("Enter a string ")
list1 = list(list1)
list2 = copy.deepcopy(list1)
for i in list1:
if list1.index(i)%2 != 0:
print(i, list1.index(i), list2.index(i))
list2.pop(list2.index(i))
print(list2)
print(list2)
output:
Enter a string google
o 1 1
['g', 'o', 'g', 'l', 'e']
o 1 1
['g', 'g', 'l', 'e']
e 5 3
['g', 'g', 'l']
['g', 'g', 'l']
... and that's your trouble. Fix your logic. You already know the needed index to save or remove. There is no need to extract the character, and then search for it again. You already know where it is.
Even better, simply slice the original string for the characters you want:
print(list1[::2])
Your problem is the list.index function. The documentation states that it "returns zero-based index in the list of the first item whose value is equal to x." Because you are calling it on list1 - and that is not modified - the result will always be list1.index('a') == 1 for example.
The correct solution would be to use enumerate. A further problem exists here - because you are indexing from an array that you have not modified, you indexes will be off after the first list.pop operation. Every item after the one removed will have been shifted by 1. To correct this, you could instead try building a list instead of emptying one:
#!/usr/bin/python3
list1 = input("Enter a string ")
list2 = []
for i, item in enumerate(list1):
if i % 2 == 0:
list2.append(item)
print(list2)
You don't need to iterate at all. Just reference the string elements directly.
st="123456789"
print('Odd: ', list(st[::2]))
print('Even: ', list(st[1::2]))
Output:
Odd: ['1', '3', '5', '7', '9']
Even: ['2', '4', '6', '8']
The method list.index(i) returns index in the list of the first item whose value is equal to i.
For example, "saurav".index('a') returns 1. when you call list2.pop(list2.index(i)) and you want to pop an a, it doesn't work well.
I think it can be simple using range as build-in function.
list1 = list(input("Enter a string "))
list2 = list()
for i in range(len(list1)):
if i % 2 == 0:
list2.append(list1[i])
print(list2)
It works with same way by following:
list1 = list(input("Enter a string "))
list2 = list()
for i in range(0, len(list1), 2):
list2.append(list1[i])
print(list2)
Also, you can use Extended Slices in Python 2.3 or above.
list1 = list(input("Enter a string "))
list2 = list1[::2]
print(list2)

Getting elements with dynamic range of list in python

I am trying to get the elements of a list in python but with a dynamic range ie if I have two lists ['9','e','s','t','1','2','3'] and ['9','e','1','2','3','s','t'] now I need to access the three numbers including 1, so what I did was reached for 1 and then pass the index value of 1 and extract the desired values ie
s_point = valueList.index('1')
print (valueList[s_point::3]
but it does not seem to work however on const values like
print (valueList[1::3])
it seems to work just fine. is there a way I could dynamically pass range of list elements to extract out of list ?
If you want the three items after the s_point index you don't have to use the step which is ::step because the usage is different. Just change your line to this:
valueList[s_point:s_point+3]
output:
>>> [1,2,3]
This way it is going to get the sublist of valueList from the index of s_point to the three which are front of it.
And to know the usage of step as other websites mentioned:
The step is a difference between each number in the result. The
default value of the step is 1 if not specified
For example:
valueList[::2]
result:
>>> ['9','s','1','3']
As you see the odd items are not in the list.
Looks like you need
lst = ['9', 'e', '1', '2', '3', 's', 't']
print(lst[lst.index('1'):lst.index('1') + 3])
lst1 = ['9', 'e', 's', 't', '1', '2', '3']
print(lst1[lst1.index('1'):lst1.index('1') +3])
Output:
['1', '2', '3']
['1', '2', '3']
There are three problems
1) s_point = valueList.index('1')
print (valueList[s_point::3]
but it does not seem to work,
This is simply because you missed the ending parentheses of the print statement.
2) However, on const values like 1 in this example
print (valueList[1::3]) works
but it will not give the desired output rather prints the first 3 numbers.
3) Assuming when the list valuelist is defined, the alphabets used is in single quotes.
Now for the actual solution part.
If you are looking for the case wherein you need the value 1 or any dynamic value say x and the subsequent three values after that from the list. You can make use of a function or anonymous function called lambda, which should accept a dynamic parameter, and it should return the subsequent 3 or dynamic values. like shown below.
>>>
>>> valuelist = [9, 'e', 's', 't', 1, 2, 3]
>>>
>>> result = lambda x,y: valuelist[valuelist.index(x):valuelist.index(x)+y]
>>> result(1,3)
[1, 2, 3]
>>>
>>>

Python set anomaly

I'm trying to understand how sets work when I try to get values from a list.
So when I run the code at the bottom
wordlist = ['hello',1,2,3]
wordSet = set(wordlist)
Output is
{3, 1, 2, 'hello'}
or something similar because set doesn't have a order.
But my point is, when I try to reach my list's first element, like using myList[0] when using it's value to create a set
wordlist = ['hello',1,2,3]
wordSet = set(wordlist[0])
I was expecting output to be
{'hello'}
but instead, I get
{'l', 'o', 'h', 'e'}
or one of randomized style.
My point is when I put my list in set function directly, it uses entire list to create a set, but when I want to create a set with using only first element in my list, it divides my string to characters.
Why does that happen ?
Strings such as 'hello' are iterable; set() converts iterables into sets.
To clarify,
set(('1', '1', '2', '3')) == {'1', '2', '3'}
set(['1', '1', '2', '3']) == {'1', '2', '3'}
set('1123') == {'1', '2', '3'}
Calling set on an object will iterate the object. Strings are iterable, yielding individual characters. If you want a set containing only the first element of wordlist, you would need to use an iterable which only contains that element:
set([worldlist[0]])
Or, more directly, just use the curly braces:
{worldlist[0]}

Correcting a list with a dictionary and a subsequent .sort() command displays wrong string order

sorry for the bad title. I am new to programming and I could not come up with a better description.
So, I have this code:
umw = {'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
def card_ranks(ranks):
"Return a list of the ranks, sorted with higher first."
for i in ranks:
if i in umw:
index = ranks.index(i)
ranks[index] = str(umw[i])
ranks.sort(reverse = True)
return ranks
print(card_ranks(['A', '3', '4', 'K'])) #should output [14, 13, 4, 3]
This gives me the following result:
['4', '3', '14', '13']
clearing the "reverse = True" gives the following:
['13', '14', '3', '4']
If i do something like that:
r = card_ranks(['A', '3', '4', 'K'])
r[0] -> gives me '4'
but this doesnt work again:
print(sorted(r)) -> gives me ['4', '3', '14', '13'] all over again.
So it seems, that the .sort() command views the 13 & 14 as a unit and the 3 & 4.
Could somebody explain why that is?
Thanks alot!
You're sorting them lexicographically, as strings rather than numbers. You could convert them to integers first, or you could expand your umw dictionary:
umw = {str(i): i for i in range(2, 10)}
umw.update({'T':10, 'J':11, 'Q':12, 'K':13, 'A':14})
def card_ranks(ranks):
return sorted(ranks, key=umw.get, reverse=True)
card_ranks(['A', '3', '4', 'K'])
# ['A', 'K', '4', '3']
This uses the dict.get method as a key function to guide the sorting without changing the values being sorted.
You are sorting strings where '11' comes before '3'. The following sorted call deals with the necessary type conversion:
def card_ranks(ranks):
return sorted((umw[c] if c in umw else int(c) for c in ranks), reverse=True)
>>> card_ranks(['A', '3', '4', 'K'])
[14, 13, 4, 3]
For every string in ranks, the generator expression produces the corresponding value in the umw dict or, as fallback, turns the string into an int, such that a proper numerical, non-lexicographical comparison is possible.
It does not see them as a unit, it compares the charakter for charakter:
'1'<'3'<'4', so the ranking is '13'<'14'<'3'<'4'
You want all of them to be numbers, so change the following lines:
ranks[index] = str(umw[i])
to
ranks[index] = umw[i]
and:
print(card_ranks(['A', '3', '4', 'K']))
to
print(card_ranks(['A', 3, 4, 'K']))
Because the list elements are string that's why
while sorting its taking in account every character i.e. every digit in the number
Which means every string char is sorted by its first character and then by its next character
Which means "233" < "3" and "1111" < "233"
umw = {'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
def card_ranks(ranks):
"Return a list of the ranks, sorted with higher first."
for i in ranks:
if i in umw:
index = ranks.index(i)
ranks[index] = str(umw[i])
ranks = list(map(int, ranks)) # The line to be added
ranks.sort(reverse = True)
return ranks
print(card_ranks(['A', '3', '4', 'K'])) #sh
You need to convert the list elements to int by ranks = list(map(int, ranks)) before sorting the list
ranks[index] = str(umw[i])
You are saving the values as strings instead of integers. And it is sorting them as strings.
Try
ranks[index] = int(umw[i])

How do I remove hyphens from a nested list?

In the nested list:
x = [['0', '-', '3', '2'], ['-', '0', '-', '1', '3']]
how do I remove the hyphens?
x = x.replace("-", "")
gives me AttributeError: 'list' object has no attribute 'replace', and
print x.remove("-")
gives me ValueError: list.remove(x): x not in list.
x is a list of lists. replace() will substitute a pattern string for another within a string. What you want is to remove an item from a list. remove() will remove the first occurrence of an item. A simple approach:
for l in x:
while ("-" in l):
l.remove("-")
For more advanced solutions, see the following: Remove all occurrences of a value from a Python list

Categories

Resources