Python ranking and lists - python

I have this script that is suppose to rank fruits based on a number.
#! /usr/bin/python
fruits = {'Apple':1,'Banana':2,'Pineapple':3}
alist = [(v, k) for k, v in fruits.items()]
alist.sort(reverse=False)
fruit_order = str(alist).translate(None, "[]()'123456789").replace(", , ", " , ",").replace(" ", "")[1:]
print fruit_order
fruits is actully a list made up with check with .append(fruits)
#! /usr/bin/python
import re
from configobj import ConfigObj
config = ConfigObj('sites.conf')
fruits = []
substance = "juice"
target_list = config['MainConfig']['fruits']
for target in target_list:
if re.search( config[target]['Skiplist'], substance, re.M|re.I):
target = target + "'" + ":" + config[target]['Rank'] + ","
fruits.append(target)
else:
print "Dident pass"
fruits1 = "{'" + "'".join(fruits) + "}"
alist = [(v, k) for k, v in fruits1.list()]
alist.sort(reverse=False)
fruit_rank = str(alist).translate(None, "[]()'123456789").replace(", , ", ",").replace(" ", "")[1:]
print fruit_rank in example 2 prints out a line that looks exactly like test in example 1.
But iam still getting an error on example2, AttributeError: 'str' object has no attribute 'list'
And i can not really figure this one out. How would i do it?
What iam looking for is in the config file i have a rank for each fruit, the line should print out the fruits in its rank.

fruits = {'Apple': 1,'Banana': 2,'Pineapple': 3}
print ','.join(sorted(fruits, key=fruits.get))

You should use the builtin function sorted, and specify that you wish to sort by the ranks instead of by the names themselves. For your first example, here is what I would do. It sorts the dict's keys (the fruit names) by its values (their ranks).
fruits = {'Apple':1,'Banana':2,'Pineapple':3}
sorted_keys = sorted(fruits.keys(), key=lambda k: fruits[k])
Your second example is very hard to read. I would recommend that you comment code that is that complex.
It looks like you are trying to create a string containing Python code, and then execute that code. Like an eval statement. That is not good programming practice. You will want to do something like:
fruits = {} # create dict
for line in my_file.readlines():
fruit_name, rank = function_to_parse_line(line)
fruits[fruit_name] = rank
sorted_keys = sorted(fruits.keys(), key=lambda k: fruits[k])
Now there is a nice separation between the code that reads the data and the code that sorts it. If you wanted to read data from a different kind of file, you can just redefine function_to_parse_line.

Related

How do you convert the quotient of a division of two polynomials to a standard polynomial instead of a tuple in Python [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Python 2 equivelant of print(*array) [duplicate]

I would like to know if there is a better way to print all objects in a Python list than this :
myList = [Person("Foo"), Person("Bar")]
print("\n".join(map(str, myList)))
Foo
Bar
I read this way is not really good :
myList = [Person("Foo"), Person("Bar")]
for p in myList:
print(p)
Isn't there something like :
print(p) for p in myList
If not, my question is... why ? If we can do this kind of stuff with comprehensive lists, why not as a simple statement outside a list ?
Assuming you are using Python 3.x:
print(*myList, sep='\n')
You can get the same behavior on Python 2.x using from __future__ import print_function, as noted by mgilson in comments.
With the print statement on Python 2.x you will need iteration of some kind, regarding your question about print(p) for p in myList not working, you can just use the following which does the same thing and is still one line:
for p in myList: print p
For a solution that uses '\n'.join(), I prefer list comprehensions and generators over map() so I would probably use the following:
print '\n'.join(str(p) for p in myList)
I use this all the time :
#!/usr/bin/python
l = [1,2,3,7]
print "".join([str(x) for x in l])
[print(a) for a in list] will give a bunch of None types at the end though it prints out all the items
For Python 2.*:
If you overload the function __str__() for your Person class, you can omit the part with map(str, ...). Another way for this is creating a function, just like you wrote:
def write_list(lst):
for item in lst:
print str(item)
...
write_list(MyList)
There is in Python 3.* the argument sep for the print() function. Take a look at documentation.
Expanding #lucasg's answer (inspired by the comment it received):
To get a formatted list output, you can do something along these lines:
l = [1,2,5]
print ", ".join('%02d'%x for x in l)
01, 02, 05
Now the ", " provides the separator (only between items, not at the end) and the formatting string '02d'combined with %x gives a formatted string for each item x - in this case, formatted as an integer with two digits, left-filled with zeros.
To display each content, I use:
mylist = ['foo', 'bar']
indexval = 0
for i in range(len(mylist)):
print(mylist[indexval])
indexval += 1
Example of using in a function:
def showAll(listname, startat):
indexval = startat
try:
for i in range(len(mylist)):
print(mylist[indexval])
indexval = indexval + 1
except IndexError:
print('That index value you gave is out of range.')
Hope I helped.
I think this is the most convenient if you just want to see the content in the list:
myList = ['foo', 'bar']
print('myList is %s' % str(myList))
Simple, easy to read and can be used together with format string.
I recently made a password generator and although I'm VERY NEW to python, I whipped this up as a way to display all items in a list (with small edits to fit your needs...
x = 0
up = 0
passwordText = ""
password = []
userInput = int(input("Enter how many characters you want your password to be: "))
print("\n\n\n") # spacing
while x <= (userInput - 1): #loops as many times as the user inputs above
password.extend([choice(groups.characters)]) #adds random character from groups file that has all lower/uppercase letters and all numbers
x = x+1 #adds 1 to x w/o using x ++1 as I get many errors w/ that
passwordText = passwordText + password[up]
up = up+1 # same as x increase
print(passwordText)
Like I said, IM VERY NEW to Python and I'm sure this is way to clunky for a expert, but I'm just here for another example
Assuming you are fine with your list being printed [1,2,3], then an easy way in Python3 is:
mylist=[1,2,3,'lorem','ipsum','dolor','sit','amet']
print(f"There are {len(mylist):d} items in this lorem list: {str(mylist):s}")
Running this produces the following output:
There are 8 items in this lorem list: [1, 2, 3, 'lorem', 'ipsum',
'dolor', 'sit', 'amet']
OP's question is: does something like following exists, if not then why
print(p) for p in myList # doesn't work, OP's intuition
answer is, it does exist which is:
[p for p in myList] #works perfectly
Basically, use [] for list comprehension and get rid of print to avoiding printing None. To see why print prints None see this
To print each element of a given list using a single line code
for i in result: print(i)
You can also make use of the len() function and identify the length of the list to print the elements as shown in the below example:
sample_list = ['Python', 'is', 'Easy']
for i in range(0, len(sample_list)):
print(sample_list[i])
Reference : https://favtutor.com/blogs/print-list-python
you can try doing this: this will also print it as a string
print(''.join([p for p in myList]))
or if you want to a make it print a newline every time it prints something
print(''.join([p+'\n' for p in myList]))

Print 'key' if given 'value' matches in python dictionary

I want to check if the 'value' exists in python dictionary and if matches print the 'key'. The problem is, values are in the list.
This script will give the server name based on the provided domain name. It will query the predefined nameserver and gives output accordingly.
I have tried following but it keeps giving me the same output.
if [k for k, v in servers.iteritems() if answer in v]:
print "\nThe domain is in " + v + ".\n"
The script is as follows. Any suggestions other than the original one is welcome.
#!/usr/bin/python
import dns.resolver
import sys
servers = {
'UK':['127.0.0.1'],
'USA':['127.0.0.2','127.0.0.3','127.0.0.4'],
'AUS':['127.0.1.1','127.0.1.2']
}
website = sys.argv[1]
try:
nameserver = dns.resolver.Resolver(configure=False)
nameserver.nameservers = ['198.40.3.6','198.40.3.7']
answer = nameserver.query(website)[0]
answer = str(answer)
if [k for k, v in servers.iteritems() if answer in v]:
print "\nThe domain is in " + v + ".\n"
except Exception as e:
print str(e)
It should give the correct 'key' but it is not. It is giving the same output.
The logic of your if check and the print statement following it are faulty. There's nothing specifically incorrect about how you're finding keys (though you could do it more efficiently), but you're not using that result at all in the rest of your code, so it doesn't really matter.
Try changing your code to this:
matched_keys = [k for k, v in servers.iteritems() if answer in v] # same list comp as before
if matched_keys:
print print "\nThe domain is in " + str(matched_keys) + ".\n" # or maybe use matched_keys[0]?
The way I coded it above will print out the list of all keys that have the answer in them, if there are any. If you're sure there can only be one result, you can use matched_keys[0].
Note that if you expect to be doing this sort of check a lot, with the same set of servers, you should probably change your data structure so that you can do a more efficient check. The current one is O(M*N) where M is the number of checks you need to do and M is the number of values in the dictionary. You could turn that into O(M) by constructing a reversed dictionary:
reversed_servers = {}
for k, v in servers.iteritems():
for address in v:
reversed_servers.setdefault(address, []).append(k) # or reversed_servers[address] = k
You only need to do this setup once. Later you can do any number of efficent lookups with just reversed_servers[answer], with no loop needed.
Note that the code above sets up a dictionary containing lists of all matching keys, if there can be only one for each address (because the values are unique), then you can use the alternative version in the comment, which will map from address to key directly (without a list).
Try this:
result = [k for k in servers.keys() if answer in servers[k]]
if result:
print "\nThe domain is in " + str(servers[result[0]]) + ".\n"
To print the corresponding key, you can use result[0].

What's wrong with this code Python 3.3

I'm trying to create a small Python program which calls a random student in lessons then it removes this student from the list till all other students are called.
Example :
ME
You
Others
I want to call randomly one and then remove it from the list so the next time it would be only
You
Others
I've wrote this code but it keeps repeating students without first calling all of them.
import random
klasa = {1 :'JOHN', 2 : 'Obama' , 3 : 'Michele' , 4 : 'Clinton'}
ran = []
random.seed()
l = random.randint(1,4)
while l not in ran:
ran.append(l)
print(klasa[l])
for x in ran:
if x != None:
ran.remove(x)
else:
break
There are two approaches you could take. One is to have a list of keys in the dictionary, select a key randomly from this list and then remove it. This would look like this:
from random import choice
keys = klasa.keys()
while keys: #while there are keys left in 'keys'
key = choice(keys) #get a random key
print("Calling %s" % (klasa.pop(key))) #get the value at that key, and remove it
keys.remove(key) #remove key from the list we select keys from
klasa.pop(key) will return the value associated with the key in addition to deleting it:
| pop(...)
| D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
| If key is not found, d is returned if given, otherwise KeyError is raised
Another approach is to shuffle the list of keys before hand and go over each one, i.e:
from random import shuffle
keys = klasa.keys()
shuffle(keys) #put the keys in random order
for key in keys:
print("Calling %s" % (klasa.pop(key)))
If you want to delete people one person at time, you can simply do:
print("Calling %s" % klasa.pop(choice(klasa.keys())))
Though this means you will generate a list of the keys each time, it's better to store this in a list and remove the keys from this list as you delete them like in the first suggested method. keys = .keys() ... a_key = choice(keys), klasa.pop(key), keys.delete(key)
Note: In python 3.x you need to go keys = list(klasa) as .keys doesn't return a list like 2.x
I tried for simplicity:
>>> klasa = ['JOHN', 'Obama' , 'Michele' , 'Clinton']
>>> random.seed()
>>> l = len(klasa)
>>> while l > 0:
... i = random.randint(0,l-1)
... print (klasa[i])
... del klasa[i]
... l=len(klasa)
...
Michele
JOHN
Obama
Clinton
>>>
Modify this Solution According to your Needs
from random import *
klasa = {1 :'JOHN', 2 : 'Obama' , 3 : 'Michele' , 4 : 'Clinton'}
#Picks a random Student from the Dictionary of Students
already_called_Student=klasa[randint(1,4)]
print "Selected Student is" , already_called_Student
total_Students = len(klasa)
call_student_number = 0
while call_student_number < total_Students:
random_student=klasa[randint(1,4)]
if random_student == already_called_Student:
continue
print random_student
call_student_number = call_student_number + 1

Add new item to Dictionary dynamically using a variable

I'm currently reading values from file and spliting them as parameter and value e.g. #id=7 becomes param = #id, value = 7. I would like to use the param variable as a new key in the dictionary. However, it is not working as expected. I'm using the following code.
list1 = {}
with open('C:/Temp/file1.txt') as f:
lines = f.read().splitlines()
for line in lines:
middle = line.find("=")
param = line[:middle]
value = line[middle+1:]
list1[param] = value
In this code, the dictionary key and value becomes 7.
Thanks in advance.
You have to define your dictionary (d is a nice name). You can do it this way:
with open('C:/Temp/file1.txt') as f:#
d = dict(line.strip().split('=', 1) for line in f)
for k,v in d.iteritems():
print("param = {0}, value = {1}".format(k,v))
If you are defining list1 as a dict list1 = {} then your print statement is incorrect.
print("param = " + list1[param] + ", value = " + value)
both list1[param] and value would be 7. since list1[param] would give you the value of it's contents and not it's key.
Try looking at the dictionary afterwards by printing it.
print(list1)
I know this wasn't what you were asking for, but I would suggest to look at ConfigParser. This is a standard way to use configuration files.

Categories

Resources