How to use a dictionary to print its partner value - python

Not sure if the title is specific enough.
words = ['sense', 'The', 'makes', 'sentence', 'perfect', 'sense', 'now']
numbers = ['1', '2', '3', '4', '5', '6']
dictionary = dict(zip(numbers, words))
print(dictionary)
correctorder = ['2', '4', '7', '3', '5', '6']
I'm simply trying to figure out how exactly I can print specific values from the dictionary using the correctorder array so that the sentence makes sense.

You can just iterate over correctorder and get the corresponding dict value, then join the result together.
' '.join(dictionary[ele] for ele in correctorder)
This is assuming that you fix numbers to include '7' at the end.
>>> ' '.join(dictionary[ele] for ele in correctorder)
'The sentence now makes perfect sense'

What you want is this.
for i in correctorder:
print dictionary[i]," ",
Short and simple. As Mitch said, fix the 7 though.

You could use operator.itemgetter to avoid an explicit loop:
>>> from operator import itemgetter
>>> print(itemgetter(*correctorder)(dictionary))
To concatenate this simply use str.join:
>>> ' '.join(itemgetter(*correctorder)(dictionary))

Related

How to reverse a list of strings without reversed() or [::-1] in Python

I made a post about this recently but didn't go into proper detail and I don't really know how commenting works on this website so I thought I'd create another thread with proper detail (if that's okay, sorry if it isn't)
Simply put, I'm writing code that prompts for and reads a string from a user (eg: 12345). This string could be infinitely long (eg: 123456789123456789, etc). After this string is entered, my code then takes each element from that string and puts it into a list (eg, 12345 is turned into ['1', '2', '3', '4', '5']).
What I need help with is reversing this list of strings without using reversed() or [::-1], and for it to work with a list of strings that could be infinitely long (eg, ['1', '2', '3', '4', '5'] turns into ['5', '4', '3', '2', '1']).
I know this is very basic, but I've spent quite a while trying to think of how to do this and for some reason my slow brain can't grasp a way how to. The best way for me to learn is to see it being done, with an explanation as to how it works (or I could look at the code and figure out the 'how' part by myself). I would be extremely appreciative for help on this, and thankyou in advance!
How about this
x = input('enter the values:')
x = list(x)
res = []
for i in range(len(x) -1, -1, -1):
res.append(x[i])
print(res)
In addition to using reversed() or L[::-1], you could use list.reverse() to reverse the elements of the list in-place:
>>> L = ['1', '2', '3', '4', '5']
>>> L.reverse()
>>> L
['5', '4', '3', '2', '1']
You can implement reversed() yourself with a for loop:
>>> L = ['1', '2', '3', '4', '5']
>>> R = []
>>> for i in range(len(L)-1, -1, -1):
... R.append(L[i])
...
>>> R
['5', '4', '3', '2', '1']
lst1 = [1,2,3,4,5,6]
reversed_list = []
length = len(lst1)
for r in range(0, length ):
reversed_list.append( lst1[length - r - 1] )
print reversed_list
x="hey there"
l=len(x)
out=''
while l:
out=out+x[l-1]
l-=1
print out
This is what you are looking for. Start at end of sting on work backwards and append it to an out var

trying to prepend zeroes in python but getting strange results

I am trying to take a list of strings, and prepend an amount of zeroes to the front so that they are all the same length. I have this:
def parity(binlist):
print(binlist)
for item in binlist:
if len(item)==0:
b='000'
elif len(item)==1:
b='00{}'.format(item)
elif len(item)==2:
b='0{}'.format(item)
binlist.remove(item)
binlist.append(b)
return binlist
This is binlist:
['1', '10', '11', '11']
and i want to get this after running it:
['001', '010', '011', '011']
but I get this:
['10', '11', '11', '001']
which really confuses me.
thanks for any help at all.
Try this:
>>> n = "7"
>>> print n.zfill(3)
>>> "007"
This way you will have always a 3 chars string (if the number is minor than 1000)
http://www.tutorialspoint.com/python/string_zfill.htm
The native string formatting operations allow you to do this without all the trouble you're putting in. Here's an example.
x = ['1', '10', '11', '11']
print ["{:>03s}".format(t) for t in x]
['001', '010', '011', '011']
This is caused because you are deleting the elements in the list while iterating through the list using a for loop. Doing so does not iterate over the full list. You can use a while loop to solve this problem.
You can do this in a one-liner using zfill:
>>> map(lambda binlist_item: binlist_item.zfill(3), ['1', '10', '11', '11'] )
['001', '010', '011', '011']
Fill with zeros for each item in the list
binlist = [i.zfill(3) for i in binlist]

python split string number in digits

Hi I would like to split the following string "1234" in ['1', '2', '3', '4'] in python.
My current approach is using re module
import re
re.compile('(\d)').split("1234")
['', '1', '', '2', '', '3', '', '4', '']
But i get some extra empty strings. I am not an expert in regular expressions, what could be a proper regular expression in python to accomplish my task?
Please give me some advices.
Simply use list function, like this
>>> list("1234")
['1', '2', '3', '4']
The list function iterates the string, and creates a new list with all the characters in it.
Strings are by default character lists:
>>> nums = "1234"
>>> for i in nums:
... print i
...
1
2
3
4
>>> nums[:-1]
'123'

How to remove specific strings from a list

From the following list how can I remove elements ending with Text.
My expected result is a=['1,2,3,4']
My List is a=['1,2,3,4,5Text,6Text']
Should i use endswith to go about this problem?
Split on commas, then filter on strings that are only digits:
a = [','.join(v for v in a[0].split(',') if v.isdigit())]
Demo:
>>> a=['1,2,3,4,5Text,6Text']
>>> [','.join(v for v in a[0].split(',') if v.isdigit())]
['1,2,3,4']
It looks as if you really wanted to work with lists of more than one element though, at which point you could just filter:
a = ['1', '2', '3', '4', '5Text', '6Text']
a = filter(str.isdigit, a)
or, using a list comprehension (more suitable for Python 3 too):
a = ['1', '2', '3', '4', '5Text', '6Text']
a = [v for v in a if v.isdigit()]
Use str.endswith to filter out such items:
>>> a = ['1,2,3,4,5Text,6Text']
>>> [','.join(x for x in a[0].split(',') if not x.endswith('Text'))]
['1,2,3,4']
Here str.split splits the string at ',' and returns a list:
>>> a[0].split(',')
['1', '2', '3', '4', '5Text', '6Text']
Now filter out items from this list and then join them back using str.join.
try this. This works with every text you have in the end.
a=['1,2,3,4,5Text,6Text']
a = a[0].split(',')
li = []
for v in a:
try : li.append(int(v))
except : pass
print li

How to improve the following list-to-list look up in Python?

I have the following list_A:
['0', '1', '2', '3', '4', '5', '6', '7']
and this other list_B:
['2','6','7']
I would like to check this: For each element in "list_A", if it is one of the elements in "list_B"
So:
for 0 <-> are you one of these? ['2','6','7']
for 1 <-> are you one of these? ['2','6','7']
for 2 <-> are you one of these? ['2','6','7']
And at the end, I would like to come up with a "list_C" that is identical to "list_A" in terms of element count but more like a map that looks like that:
['-1', '-1', '2', '-1', '-1', '-1', '6', '7']
Which is: "-1" for every non-matching element and "self" for every matching one. Obviously I am doing this with 2 nested for each cycles, and it works:
myStateMap = []
for a in list_A:
elementString = -1
for b in list_B:
if a == b:
# Update the elementString in case of a match
elementString = a
print "\tMatch"
else:
pass
print "\tNO Match!"
# Store the elementString
myStateMap.append(elementString)
The question is: How would you optimize this? How would you make it shorter and more efficient?
You can use a list comprehension:
>>> [('-1' if item not in list_B else item) for item in list_A]
['-1', '-1', '2', '-1', '-1', '-1', '6', '7']
Use a list comprehension with a conditional expression:
[i if i in list_B else '-1' for i in list_A]
Demo:
>>> list_A = ['0', '1', '2', '3', '4', '5', '6', '7']
>>> list_B = ['2','6','7']
>>> [i if i in list_B else '-1' for i in list_A]
['-1', '-1', '2', '-1', '-1', '-1', '6', '7']
if list_B is large, you should make it a set instead:
set_B = set(list_B)
to speed up the membership testing. in on a list has linear cost (the more elements need to be scanned, the longer it takes), while the same test against a set takes constant cost (independent of the number of values in the set).
For your specific example, using a set is already faster:
>>> timeit.timeit("[i if i in list_B else '-1' for i in list_A]", "from __main__ import list_A, list_B")
1.8152308464050293
>>> timeit.timeit("set_B = set(list_B); [i if i in set_B else '-1' for i in list_A]", "from __main__ import list_A, list_B")
1.6512861251831055
but if list_A ratios list_B are different and the sizes are small:
>>> list_A = ['0', '1', '2', '3']
>>> list_B = ['2','6','8','10']
>>> timeit.timeit("[i if i in list_B else '-1' for i in list_A]", "from __main__ import list_A, list_B")
0.8118391036987305
>>> timeit.timeit("set_B = set(list_B); [i if i in set_B else '-1' for i in list_A]", "from __main__ import list_A, list_B")
0.9360401630401611
That said, in the general case it is worth your while using sets.
The quickest way to optimize is to use if a in list_B: instead of your inner loop. So the new code would look like:
for a in list_A:
if a in list_B:
myStateMap.append(a)
print '\tMatch'
else:
print '\tNO Match!'
myStateMap.append(-1)
Here's another short list comprehension example that's a little different from the others:
a=[1,2,3,4,5,6,7]
b=[2,5,7]
c=[x * (x in b) for x in a]
Which gives c = [0, 2, 0, 0, 5, 6, 7]. If your list elements are actually strings, like they seem to be, then you either get the empty string '' or the original string. This takes advantage of the implicit conversion of a boolean value (x in b) to either 0 or 1 before multiplying it by the original value (which, in the case of strings, is "repeated concatenation").

Categories

Resources