trying to prepend zeroes in python but getting strange results - python

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]

Related

Python, list.remove() does not work right

Hello I am trying to remove first and last 2 element of my list.
My list is: ['12','30','22','06','27','13','23','16','14','20','09','29','23']
and this is the code I am using:
dList.remove(dList[0])
dList.remove(dList[-1])
dList.remove(dList[-1])
It works right too many other list but in this list it returns:
['30', '22', '06', '27', '13', '16', '14', '20', '09', '29']
Instead of;
['30', '22', '06', '27', '13', '23', '16', '14', '20', '09',]
I noticed the last element is '23' and both '23' be removed but I don't know how to fix it. It should be work right because I remove first element, and last element, and last element again. I didn't use:
a = dList[0]
dList.remove(a)
a = dList[-1]
dList.remove(a)
a = dList[-1]
dList.remove(a)
The remove() method removes the first matching element (which is passed as an argument) from the list.
You have 23 repeated twice.
If you want to remove index you can use del in your example.it would be:
del dList[-1]
Why not using pop to pop out the last element of the list?
last_element = dList.pop()
semilast_element = dList.pop()
You can even put the index of the element you want to pop
first_element = dList.pop(0)
second_element = dList.pop(0)
Always refer to the original documentation
With:
dList = ['12','30','22','06','27','13','23','16','14','20','09','29','23']
...you could construct a new list with a slice (as previously suggested) like this:
dList = dList[1:-2]
...or you can do it in situ using pop() as follows:
dList.pop(0)
dList.pop()
dList.pop()

How make a if statement more correctly? (If the random number contains a number from the list, then...)

i want to make a code (Lucky ticket, aka lottery) - with can generate random 6-dight number, after that - programm will check a list (with contain a lucky numbers for win: '11', '22', '33' and etc.) and say - are you win or not. But - theres one problem, i cant make if statement correctly, it always gives me error, not right result with i want. List are contain 9 values:
luckynumber = '11', '22', '33', '44', '55', '66', '77', '88', '99'.
try this:
if luckynumber in ["put all the lucky numbers in this list"]:
pass # do whatever you want
One problem you might be having is that in order to compare random_numberwith lucky_numbers, they both need to be strings i.e.,
lucky_numbers = ['11', '22', '33', '44', '55', '66', '77', '88', '99']
random_number = str(random_number) # assuming you already made random_number
You can then compare the two with any(), e.g.
result = any(r in random_number for r in lucky_number)
If you don't convert to random_number to a string, you'll get the error
TypeError: argument of type 'int' is not interable

Break a binary string down to segments

The task here is to break down a string 110011110110000 into a list:
['11', '00', '1111', '0', '11', '0000']
My solution is
str1='110011110110000'
seg = []
a0=str1[0]
seg0=''
for a in str1:
print('a=',a)
if a==a0:
seg0=seg0+a
else:
print('seg0=',seg0)
seg.append(seg0)
seg0=a
a0=a
seg.append(seg0)
seg
It's ugly and I am sure you guys out there have a one-liner for this. Maybe regex?
You can use itertools.groupby (doc):
str1='110011110110000'
from itertools import groupby
l = [v * len([*g]) for v, g in groupby(str1)]
print(l)
Prints:
['11', '00', '1111', '0', '11', '0000']
EDIT: version with regex:
str1='110011110110000'
import re
print([g[0] for g in re.findall(r'((\d)\2*)', str1)])
Here is a regex solution:
result = [x[0] for x in re.findall(r'(([10])\2*)', str1)]
The regex is (([10])\2*), find a 0 or 1, then keep looking for that same thing. Since findall returns all groups in the match, we need to map it to the first group (Group 2 is the ([10]) bit).
Here is an iterative regex approach, using the simple pattern 1+|0+:
str1 = "110011110110000"
pattern = re.compile(r'(1+|0+)')
result = []
for m in re.finditer(pattern, str1):
result.append(m.group(0))
print(result)
This prints:
['11', '00', '1111', '0', '11', '0000']
Note that we might want to instead use re.split here. The problem with re.split is that it doesn't seem to support splitting on lookarounds. In other languages, such as Java, we could try splitting on this pattern:
(?<=0)(?=1)|(?<=1)(?=0)
This would nicely generate the array/list we expect.
one line solution using groupy
from itertools import groupby
text='1100111101100001'
sol = [''.join(group) for key, group in groupby(text)]
print(sol)
output
['11', '00', '1111', '0', '11', '0000', '1']
not regex solution, but improvement on ur code
str1='110011110110000'
def func(string):
tmp = string[0]
res =[]
for i, v in enumerate(string, 1):
if v==tmp[-1]:
tmp+=v
else:
res.append(tmp)
tmp=v
res.append(tmp)
return res
print(func(str1))
output
['111', '00', '1111', '0', '11', '0000']
You can use general regex (.)\1*
(.) - match single character (any) and store it in first capturing group
\1* - repeat what's ca[ptured in first captruing group zero or more times
Demo
Matches collection will be your desired result.

Python Combine Repeating Elements

I have a list of stings that have some repeating elements that I want to combine into a shorter list.
The original list contents look something like this:
lst = [['0.1', '0', 'RC', '100'],
['0.2', '10', 'RC', '100'],
['0.3', '5', 'HC', '20'],
['0.4', '5', 'HC', '20'],
['0.5', '5', 'HC', '20'],
['0.6', '5', 'HC', '20'],
['0.7', '5', 'HC', '20'],
['0.8', '5', 'HC', '20'],
['0.9', '10', 'RC', '100'],
['1.0', '0', 'RC', '100']]
After running it through the function it would become:
lst = [['0.1', '0', 'RC', '100'],
['0.2', '10', 'RC', '100'],
['0.3', '5', 'HC', '20'],
['0.9', '10', 'RC', '100'],
['1.0', '0', 'RC', '100']]
The list will always have this general structure, so essentially I want to combine the list based on whether or not the last 3 columns are exactly the same.
I want it to be a callable function so it would look some thing like:
def combine_list(lst):
if sublist[1:3] == next_sublist[1:3]:
let.remove(next_sublist)
My initial research on this showed many methods to remove a sublist based on its index, but that is not necessarily known before hand. I also found the re module, however I have never used it and unsure on how to implement it. Thank you in advanced
If you want to remove sub lists that are the same for the last three elements and consecutive, you would need itertools.groupby keyed on the last three elements:
from itertools import groupby
[next(g) for _, g in groupby(lst, key=lambda x: x[1:])]
#[['0.1', '0', 'RC', '100'],
# ['0.2', '10', 'RC', '100'],
# ['0.3', '5', 'HC', '20'],
# ['0.9', '10', 'RC', '100'],
# ['1.0', '0', 'RC', '100']]
Maybe just use a set to keep track of duplicates?
def combine_list(lst):
out = []
seen = set()
for item in lst:
if not tuple(item[1:]) in seen:
out.append(item)
seen.add(tuple(item[1:]))
return out
Lists are a mutable data structure. And so there is no guarantee that the contents of a list does not change over time. That means it cannot be used in a hashing function (which the set uses). The tuple, on the other hand, is immutable, and hence hashable.
for index in range(len(lst) - 1, 0, -1):
if lst[index][1:] == lst[index - 1][1:]:
lst.pop(index)
By going through the list backwards, we remove the problems with indices changing when we remove elements. This results in an in-place reduction.
If you'd like to make a new list, this can be done via list comprehension following the same idea, but since we're not doing it in place, we don't have to work in reverse:
lst[0] + [lst[ind] for ind in range(1, len(lst)) if lst[ind][1:] != lst[ind-1][1:]]
Again, lst[0] is trivially non-duplicate and therefore automatically included.
def combine_list(ls):
cpy = ls[:]
for i, sub in enumerate(ls[:len(ls) - 1]):
if sub[1:] == ls[i + 1][1:]:
cpy.remove(ls[i + 1])
return cpy
This function should work. It creates a new copy of the list, to avoid modifying the original. Then it iterates over the original list (except the last value), as that stays the same.
It then checks if the last values of the list are equal to the last values of the next list. If they are, the next list is deleted.
The function then returns the new list.

How to use a dictionary to print its partner value

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

Categories

Resources