Removing characters from a tuple - python

Im using
Users = win32net.NetGroupGetUsers(IP,'none',0),
to get all the local users on a system. The output is a tuple,
(([{'name': u'Administrator'}, {'name': u'Guest'}, {'name': u'Tom'}], 3, 0),)
I want to clean this up so it just prints out "Administrator, Guest, Tom". I tried using strip and replace but you cant use those on tuples. Is there a way to convert this into a string so i can manipulate it or is there an even simpler way to go about it?

This should not end with a comma:
Users = win32net.NetGroupGetUsers(IP,'none',0),
The trailing comma turns the result into a single item tuple containing the result, which is itself a tuple.
The data you want is in Users[0].
>>> print Users[0]
[{'name': u'Administrator'}, {'name': u'Guest'}, {'name': u'Tom'}]
To unpack this list of dictionaries we use a generator expression:
Users = win32net.NetGroupGetUsers(IP,'none',0)
print ', '.join(d['name'] for d in Users[0])

', '.join(user['name'] for user in Users[0][0])

input = (([{'name': u'Administrator'}, {'name': u'Guest'}, {'name': u'Tom'}], 3, 0),)
in_list = input[0][0]
names = [x['name'] for x in in_list]
print names
[u'Administrator', u'Guest', u'Tom']

Related

The most efficient way to convert a string with keys and values into a python dict

How do I convert a string
{"key"=>"Number of Contents in Sales Package", "value"=>"Pack of 3"}
into a dictionary like
{'Number of Contents in Sales Package':'Pack of 3'}?
You can use str.replace and then ast.literal_eval to convert your string to a dictionary, then restructure:
from ast import literal_eval
x = '{"key"=>"Number of Contents in Sales Package", "value"=>"Pack of 3"}'
d = literal_eval(x.replace('=>', ':'))
d = {d['key']: d['value']}
print(d)
{'Number of Contents in Sales Package': 'Pack of 3'}
using re with an example with more than 1 key-value pair
import re
s = """{"key"=>"Number of Contents in Sales Package", "value"=>"Pack of 3"},
{"key"=>"Number of Contents in Sales Package 2", "value"=>"Pack of 5"}"""
pattern = re.compile(r'''{"key"=>"(?P<key>.*?)", "value"=>"(?P<value>.*?)"}''')
dict(pattern.findall(s))
{'Number of Contents in Sales Package': 'Pack of 3',
'Number of Contents in Sales Package 2': 'Pack of 5'}
You could do:
result = dict([k_v.replace('"', '').split('=>')
for k_v in string[1:-1].split(', ')])
This would require your data to be in the form:
'{key1=>value1, key2=>value2}'
Here is an approach that splits and cleans up the string a bit and then uses dict comprehension with zip() on slices of odd and even list elements (keys are even, values are odd) to generate the output you are looking for (and will work on strings that contain multiple key value pairs but not very well if your strings contain nested dicts, lists, etc).
That said, the answer from #jpp is really clever.
text = '{"key"=>"Number of Contents in Sales Package", "value"=>"Pack of 3"}'
items = [t.split('=>')[1].replace('"', '') for t in text[1:-1].split(',')]
result = {k: v for k, v in zip(items[::2], items[1::2])}
print(result)
# OUTPUT
# {'Number of Contents in Sales Package': 'Pack of 3'}

Checking the elements of a list for multiple strings

Say I have a list:
['[name]\n', 'first_name,jane\n', 'middle_name,anna\n', 'last_name,doe\n', '[age]\n', 'age,30\n', 'dob,1/1/1988\n']
How could I check if the strings 'jane', 'anna' and 'doe' are ALL contained in an element of the list.
For each name you can use any to see if it is contained in any of the strings in the list, then make sure this is true for all of the names
>>> data = ['[name]\n', 'first_name,jane\n', 'middle_name,anna\n', 'last_name,doe\n', '[age]\n', 'age,30\n', 'dob,1/1/1988\n']
>>> names = ['jane', 'anna', 'doe']
>>> all(any(name in sub for sub in data) for name in names)
True

Is there a better way to do 'complex' list comprehension?

I tend to use list comprehension a lot in Python because I think it is a clean way to generate lists, but often I find myself coming back a week later and thinking to myself "What the hell did I do this for?!" and it's a 70+ character nested conditional list comprehension statement. I am wondering if it gets to a certain point if I should break it out into if/elif/else, and the performance impact, if any of doing so.
My current circumstance:
Returned structure from call is a list of tuples. I need to cast it to a list, some values need to be cleaned up, and I need to strip the last element from the list.
e.g.
[(val1, ' ', 'ChangeMe', 'RemoveMe),
(val1, ' ', 'ChangeMe', 'RemoveMe),
(val1, ' ', 'ChangeMe', 'RemoveMe)]
So in this case, I want to remove RemoveMe, replace all ' ' with '' and replace ChangeMe with val2. I know it is a lot of changes, but the data I am returned is terrible sometimes and I have no control over what is coming to me as a response.
I currently have something like:
response = cursor.fetchall()
response = [['' if item == ' ' else item if item != 'ChangeMe' else 'val2' for item in row][:-1] for row in response]`
Is a nested multi-conditional comprehension statement frowned upon? I know stylistically Python prefers to be very readable, but also compact and not as verbose.
Any tips or info would be greatly appreciated. Thanks all!
Python favors one-liner, on the sole condition that these make the code more readable, and not that it complicates it.
In this case, you use two nested list comprehension, two adjacent ternary operators, a list slicing, all of this on a single line which exceeds the 100 characters... It is everything but readable.
Sometimes it's better to use a classic for loop.
result = []
for val, space, item, remove in response:
result.append([val, '', 'val2'])
And then you realise you can write it as a list comprehension much more comprehensible (assuming your filter condition is simple):
result = [[val, '', 'val2'] for val, *_ in response]
Remember, every code is written once, but it is read many times.
This is one quick way you could do a list-comprehension making use of a dictionary for mapping items:
response = [('val1', ' ', 'ChangeMe', 'RemoveMe'), ('val1', ' ', 'ChangeMe', 'RemoveMe'), ('val1', ' ', 'ChangeMe', 'RemoveMe')]
map_dict = {' ': '', 'ChangeMe': 'val2', 'val1': 'val1'}
response = [tuple(map_dict[x] for x in tupl if x != 'RemoveMe') for tupl in response]
# [('val1', '', 'val2'), ('val1', '', 'val2'), ('val1', '', 'val2')]

Python LOB to List

Using:
cur.execute(SQL)
response= cur.fetchall() //response is a LOB object
names = response[0][0].read()
i have following SQL response as String names:
'Mike':'Mike'
'John':'John'
'Mike/B':'Mike/B'
As you can see it comes formatted. It is actualy formatted like:\\'Mike\\':\\'Mike\\'\n\\'John\\'... and so on
in order to check if for example Mike is inside list at least one time (i don't care how many times but at least one time)
I would like to have something like that:
l = ['Mike', 'Mike', 'John', 'John', 'Mike/B', 'Mike/B'],
so i could simply iterate over the list and ask
for name in l:
'Mike' == name:
do something
Any Ideas how i could do that?
Many thanks
Edit:
When i do:
list = names.split()
I receive the list which is nearly how i want it, but the elements inside look still like this!!!:
list = ['\\'Mike\\':\\'Mike\\", ...]
names = ['\\'Mike\\':\\'Mike\\", ...]
for name in names:
if "Mike" in name:
print "Mike is here"
The \\' business is caused by mysql escaping the '
if you have a list of names try this:
my_names = ["Tom", "Dick", "Harry"]
names = ['\\'Mike\\':\\'Mike\\", ...]
for name in names:
for my_name in my_names:
if myname in name:
print myname, " is here"
import re
pattern = re.compile(r"[\n\\:']+")
list_of_names = pattern.split(names)
# ['', 'Mike', 'Mike', 'John', 'John', 'Mike/B', '']
# Quick-tip: Try not to name a list with "list" as "list" is a built-in
You can keep your results this way or do a final cleanup to remove empty strings
clean_list = list(filter(lambda x: x!='', list_of_names))

how to match python list using regular expression

I have following lists in python ["john","doe","1","90"] and ["prince","2","95"]. the first number column is field: id and second number field is score. I would like to use re in python to parse out the field and print. So far, I only know how to do split of field comma. Any one can help?
You better use a dictionary than a regex (which I don't see how you use here):
{'name': 'John Doe', 'id': '1', 'score': '90'}
Or better yet, use numbers:
{'name': 'John Doe', 'id': 1, 'score': 90}
You don't really need regular expression here. You can just use isinstance() and slicing.
This should do what you want :
a_list = ['john','doe','1','90']
for i, elem in enumerate(a_list):
try:
elem = int(elem)
except ValueError, e:
pass
if isinstance(elem, int):
names_part = a_list[:i-1]
id_and_score = a_list[i-1:]
print 'name(s): {0}, '.format(' '.join(names_part)), 'id: {id}, score: {score}'.format(id=id_and_score[0], score=id_and_score[1])
Though, this solution could be improve if we were know the source of your data or if there is a way to pridict the field position you can just turn your list into a dict as suggested. If you extract your data you may consider building a dict instead of a list which prevent you from having to do what above.

Categories

Resources