editing List content in Python - python

I have a variable data:
data = [b'script', b'-compiler', b'123cds', b'-algo', b'timing']
I need to convert it to remove all occurrence of "b" in the list.
How can i do that?

Not sure whether it would help - but it works with your sample:
initList = [b'script', b'-compiler', b'123cds', b'-algo', b'timing']
resultList = [str(x) for x in initList ]
Or in P3:
resultList = [x.decode("utf-8") for x in initList ] # where utf-8 is encoding used
Check more on decode function.
Also you may want to take a look into the following related SO thread.

>>> a = [b'script', b'-compiler', b'123cds', b'-algo', b'timing']
>>> map(str, a)
['script', '-compiler', '123cds', '-algo', 'timing']

strin = "[b'script', b'-compiler', b'123cds', b'-algo', b'timing']"
arr = strin.strip('[]').split(', ')
res = [part.strip("b'") for part in arr]
>>> res
['script', '-compiler', '123cds', '-algo', 'timing']

Related

how to split after each word and get the following string in an organized way?

Given the following string:
'hello0192239world0912903spam209394'
I would like to be able to split the above string into this
hello, 0192239, world, 0912903, spam, 209394
and ideally end with a list:
[hello, 0192239], [world, 0912903], [spam, 209394]
But I just don't know how to go about even the first step, splitting by word x number. I know there's the split method and something called regex but I don't know how to use it and even if it's the right thing to use
Try this:
>>> lst = re.split('(\d+)','hello0192239world0912903spam209394')
>>> list(zip(lst[::2],lst[1::2]))
[('hello', '0192239'), ('world', '0912903'), ('spam', '209394')]
>>> lst = re.split('(\d+)','09182hello2349283world892')
>>> list(zip(lst[::2],lst[1::2]))
[('', '09182'), ('hello', '2349283'), ('world', '892')]
# as a list
>>> list(map(list,zip(lst[::2],lst[1::2])))
[['', '09182'], ['hello', '2349283'], ['world', '892']]
See below. The idea is to maintain a 'mode' and flip mode every time you switch from digit to char or the other way around.
data = 'hello0192239world0912903spam209394'
A = 'A'
D = 'D'
mode = D if data[0].isdigit() else A
holder = []
tmp = []
for x in data:
if mode == A:
is_digit = x.isdigit()
if is_digit:
mode = D
holder.append(''.join(tmp))
tmp = [x]
continue
else:
is_char = not x.isdigit()
if is_char:
mode = A
holder.append(''.join(tmp))
tmp = [x]
continue
tmp.append(x)
holder.append(''.join(tmp))
print(holder)
output
['hello', '0192239', 'world', '0912903', 'spam', '209394']

python translating strings, and changing them back using dictionary

I've got this code that translates a string (that starts out as a list) using a dictionary. I wanted the code to translate the string, then un-translate it back to the original.
This is the code that I've got so far:
words = ['Abra', ' ', 'cadabra', '!']
clues = {'A':'Z', 'a':'z', 'b':'y', 'c':'x'}
def converter(words, clues):
words = ''.join(words)
for item in words:
if item in clues.keys():
words = words.replace(item, clues[item])
return words
def reversal(clues):
clues = {v: k for k, v in clues.items()}
print(clues)
x = converter(words, clues)
print(x)
reversal(clues)
x = converter(words, clues)
print(x)
Only, this will print
"Zyrz xzdzyrz!"
"Zyrz xdzyrz!"
I'm not sure why it's not printing:
"Zyrz xzdzyrz!"
"Abra cadabra!"
Is there an error in my code that is causing it to act this way? I checked clues and it IS reversed properly after it goes through the function. What am I doing wrong?
Python already has the translate method on all strings, just call it!
def converter(text, clues, reverse=False):
if reverse:
clues = {v: k for k, v in clues.items()}
table = str.maketrans(clues)
return text.translate(table)
Usage:
words = ['Abra', ' ', 'cadabra', '!']
clues = {'A':'Z', 'a':'z', 'b':'y', 'c':'x'}
# join the text into a single string:
x = ''.join(words)
# convert first
x = converter(x, clues)
print(x) # -> you get `Zyrz xzdzyrz!`
#back to original
x = converter(x, clues, reverse=True)
print(x) # -> you get `Abra cadabra!`
Looks like you're trying to do a dictionary operation in place within a function. Your function needs to return the reversed version of the dictionary which you then need to pick up in your main:
# Your stuff here
def reversal(clues):
return {v: k for k, v in clues.items()}
x = converter(words, clues)
print(x)
clues_reversed = reversal(clues)
x = converter(words, clues_reversed)
print(x)

How to replace text between parentheses in Python?

I have a dictionary containing the following key-value pairs: d={'Alice':'x','Bob':'y','Chloe':'z'}
I want to replace the lower case variables(values) by the constants(keys) in any given string.
For example, if my string is:
A(x)B(y)C(x,z)
how do I replace the characters in order to get a resultant string of :
A(Alice)B(Bob)C(Alice,Chloe)
Should I use regular expressions?
re.sub() solution with replacement function:
import re
d = {'Alice':'x','Bob':'y','Chloe':'z'}
flipped = dict(zip(d.values(), d.keys()))
s = 'A(x)B(y)C(x,z)'
result = re.sub(r'\([^()]+\)', lambda m: '({})'.format(','.join(flipped.get(k,'')
for k in m.group().strip('()').split(','))), s)
print(result)
The output:
A(Alice)B(Bob)C(Alice,Chloe)
Extended version:
import re
def repl(m):
val = m.group().strip('()')
d = {'Alice':'x','Bob':'y','Chloe':'z'}
flipped = dict(zip(d.values(), d.keys()))
if ',' in val:
return '({})'.format(','.join(flipped.get(k,'') for k in val.split(',')))
else:
return '({})'.format(flipped.get(val,''))
s = 'A(x)B(y)C(x,z)'
result = re.sub(r'\([^()]+\)', repl, s)
print(result)
Bonus approach for particular input case A(x)B(y)C(Alice,z):
...
s = 'A(x)B(y)C(Alice,z)'
result = re.sub(r'\([^()]+\)', lambda m: '({})'.format(','.join(flipped.get(k,'') or k
for k in m.group().strip('()').split(','))), s)
print(result)
I assume you want to replace the values in a string with the respective keys of the dictionary. If my assumption is correct you can try this without using regex.
First the swap the keys and values using dictionary comprehension.
my_dict = {'Alice':'x','Bob':'y','Chloe':'z'}
my_dict = { y:x for x,y in my_dict.iteritems()}
Then using list_comprehension, you replace the values
str_ = 'A(x)B(y)C(x,z)'
output = ''.join([i if i not in my_dict.keys() else my_dict[i] for i in str_])
Hope this is what you need ;)
Code
import re
d={'Alice':'x','Bob':'y','Chloe':'z'}
keys = d.keys()
values = d.values()
s = "A(x)B(y)C(x,z)"
for i in range(0, len(d.keys())):
rx = r"" + re.escape(values[i])
s = re.sub(rx, keys[i], s)
print s
Output
A(Alice)B(Bob)C(Alice,Chloe)
Also you could use the replace method in python like this:
d={'x':'Alice','y':'Bob','z':'Chloe'}
str = "A(x)B(y)C(x,z)"
for key in d:
str = str.replace(key,d[key])
print (str)
But yeah you should swipe your dictionary values like Kishore suggested.
This is the way that I would do it:
import re
def sub_args(text, tosub):
ops = '|'.join(tosub.keys())
for argstr, _ in re.findall(r'(\(([%s]+?,?)+\))' % ops, text):
args = argstr[1:-1].split(',')
args = [tosub[a] for a in args]
subbed = '(%s)' % ','.join(map(str, args))
text = re.sub(re.escape(argstr), subbed, text)
return text
text = 'A(x)B(y)C(x,z)'
tosub = {
'x': 'Alice',
'y': 'Bob',
'z': 'Chloe'
}
print(sub_args(text, tosub))
Basically you just use the regex pattern to find all of the argument groups and substitute in the proper values--the nice thing about this approach is that you don't have to worry about subbing where you don't want to (for example, if you had a string like 'Fn(F,n)'). You can also have multi-character keys, like 'F(arg1,arg2)'.

python get difference from arrays

I have the following two arrays , i am trying to see whether if the elements in invalid_id_arr exists in valid_id_arr if it doesn't exist then i would form the diff array.But from the below code i see the following in diff array ['id123', 'id124', 'id125', 'id126', 'id789', 'id666'], i expect the output to be ["id789","id666"] what am i doing wrong here
tag_file= {}
tag_file['invalid_id_arr']=["id123-3431","id124-4341","id125-4341","id126-1w","id789-123","id666"]
tag_file['valid_id_arr']=["id123-12345","id124-1122","id125-13232","id126-12332","id1new","idagain"]
diff = [ele.split('-')[0] for ele in tag_file['invalid_id_arr'] if str(ele.split('-')[0]) not in tag_file['valid_id_arr']]
Current Output:
['id123', 'id124', 'id125', 'id126', 'id789', 'id666']
Expected ouptut:
["id789","id666"]
Using a set is more efficient, but your main problem is that you weren't removing the second half of the elements in valid_id_arr.
invalid_id_arr=["id123-3431","id124-4341","id125-4341","id126-1w","id789-123","id666"]
valid_id_arr=["id123-12345","id124-1122","id125-13232","id126-12332","id1new","idagain"]
valid_id_set = set(ele.split('-')[0] for ele in valid_id_arr)
diff = [ele for ele in invalid_id_arr if ele.split('-')[0] not in valid_id_set]
print diff
output:
['id789-123', 'id666']
http://ideone.com/Q9JBw
Try sets:
invalid_id_arr = ["id123-3431","id124-4341","id125-4341","id126-1w","id789-123","id666"]
valid_id_arr = ["id123-12345","id124-1122","id125-13232","id126-12332","id1new","idagain"]
set_invalid = set(x.split('-')[0] for x in invalid_id_arr)
print set_invalid.difference(x.split('-')[0] for x in valid_id_arr)
>>> a = ["id123-3431","id124-4341","id125-4341","id126-1w","id789-123","id666"]
>>> b = ["id123-12345","id124-1122","id125-13232","id126-12332","id1new","idagain"]
>>> c = (s.split('-')[0] for s in b)
>>> [ele.split('-')[0] for ele in a if str(ele.split('-')[0]) not in c]
['id789', 'id666']
>>>

string into a list in Python

I have a str that contains a list of numbers and I want to convert it to a list. Right now I can only get the entire list in the 0th entry of the list, but I want each number to be an element of a list. Does anyone know of an easy way to do this in Python?
for i in in_data.splitlines():
print i.split('Counter32: ')[1].strip().split()
my result not i want
['12576810']\n['1917472404']\n['3104185795']
my data
IF-MIB::ifInOctets.1 = Counter32: 12576810
IF-MIB::ifInOctets.2 = Counter32: 1917472404
IF-MIB::ifInOctets.3 = Counter32: 3104185795
i want result
['12576810','1917472404','3104185795']
Given your data as
>>> data="""IF-MIB::ifInOctets.1 = Counter32: 12576810
IF-MIB::ifInOctets.2 = Counter32: 1917472404
IF-MIB::ifInOctets.3 = Counter32: 3104185795"""
You can use regex where the intent is more clear
>>> import re
>>> [re.findall("\d+$",e)[0] for e in data.splitlines()]
['12576810', '1917472404', '3104185795']
or as #jamylak as pointed out
re.findall("\d+$",data,re.MULTILINE)
Or str.rsplit which will have a edge on performance
>>> [e.rsplit()[-1] for e in data.splitlines()]
['12576810', '1917472404', '3104185795']
You are already quite far. Based on the code you have, try this:
result = []
for i in in_data.splitlines():
result.append(i.split('Counter32: ')[1].strip())
print result
you could also do:
result = [i.split('Counter32: ')[1].strip() for i in in_data.splitlines()]
Then, you can also go and look at what #Abhijit and #KurzedMetal are doing with regular expressions. In general, that would be the way to go, but I really like how you avoided them with a simple split.
My best try with the info you gave:
>>> data = r"['12576810']\n['1917472404']\n['3104185795']"
>>> import re
>>> re.findall("\d+", data)
['12576810', '1917472404', '3104185795']
you could even convert it to int or long if necesary with map()
>>> map(int, re.findall("\d+", data))
[12576810, 1917472404, 3104185795L]
>>> map(long, re.findall("\d+", data))
[12576810L, 1917472404L, 3104185795L]
This is how I'd do it.
data="""IF-MIB::ifInOctets.1 = Counter32: 12576810 ... IF-MIB::ifInOctets.2 = Counter32: 1917472404 ... IF-MIB::ifInOctets.3
= Counter32: 3104185795"""
[ x.split()[-1] for x in data.split("\n") ]
with open('in.txt') as f:
numbers=[y.split()[-1] for y in f]
print(numbers)
['12576810', '1917472404', '3104185795']
or:
with open('in.txt') as f:
numbers=[]
for x in f:
x=x.split()
numbers.append(x[-1])
print(numbers)
['12576810', '1917472404', '3104185795']
result = [(item[(item.rfind(' ')):]).strip() for item in list_of_data]
A variant using list comprehension. Iterator over all line of data, find the last index of a blank, cut down the strip from last found blank position to it's end, strip the resulting string (erase possible blanks) and put the result in a new list.
data = """F-MIB::ifInOctets.1 = Counter32: 12576810
IF-MIB::ifInOctets.2 = Counter32: 1917472404
IF-MIB::ifInOctets.3 = Counter32: 3104185795"""
result = [ (item[(item.rfind(' ')):]).strip() for item in data.splitlines()]
print result
Result:
['12576810', '1917472404', '3104185795']

Categories