Here is the given assignment + code:
Write a function even_value_set(list1, list2, list3), which receives
three lists containing integer items as arguments. The function
creates and returns a set that contains all items with even value from
all three lists.
def test():
l = [[],[],[]]
for i in range(3):
for j in range(random.randint(7,14)):
l[i].append(random.randint(1,35))
print ("List" + str(i + 1) +":",l[i])
print ("")
s = even_value_set(l[0],l[1],l[2])
print ("Return type:", str(type(s)).replace("<","").replace(">",""))
print ("Set with even values only:", end = "")
print (set(sorted(list(s))))
test()
import random
I tried using .union() and making adding lists into another before turning them into sets, but didn't have any luck.
You can do this in a simply pythonic way. This function can be written as a simple oneliner using comprehension
def even_value_set(list1, list2, list3):
return set([num for num in list1+list2+list3 if num % 2 == 0])
Basically, what we did here is concatenated all lists, fitered even numbers and then made it into a set.
You can union lists (with duplicates) with the + operation.
union_list = list1 + list2 + list3
If you only want the unique values you can call set on this list.
unique_set = set(union_list)
Now you can create a new empty set and iterate over the unqiue_set and add all the even values:
solution = set()
for v in unique_set:
if v%2==0:
solution.add(v)
def even_value_set(*lsts):
s = set()
for lst in lsts:
s |= {x for x in lst if x % 2 == 0}
return s
Also you can use starring
def even_value_set(*lsts):
return set().union(*[{x for x in lst if x % 2 == 0} for lst in lsts])
And solution with concatenation (more memory).
set comprehension is more effective than set()
def even_value_set(l1, l2, l3):
return {x for x in l1+l2+l3 if x % 2 == 0}
You can make the union of lists using +, like list1 + list2. Then just walk through the result list checking if the number is even and adding in another list.
def even_value_set(list):
result = set()
for val in list:
if val%2 == 0:
result.add(val)
return result
def test():
l = [[],[],[]]
for i in range(3):
for j in range(random.randint(7,14)):
l[i].append(random.randint(1,35))
print ("List" + str(i + 1) +":",l[i])
print ("")
uni = l[0] + l[1] + l[2]
s = even_value_set(uni)
print ("Return type:", str(type(s)).replace("<","").replace(">",""))
print ("Set with even values only:", end = "")
print (set(sorted(list(s))))
test()
import random
Is it what you want? I think your question is confusing.
Related
This question already has answers here:
Split string every nth character?
(19 answers)
Splitting a string into 2-letter segments [duplicate]
(6 answers)
Closed 2 years ago.
I want to divide text into pairs.
Input: text = "abcde"
Goal Output: result = ["ab", "cd", "e_"]
Current Output: result = ['ab', 'abcd']
My current code looks like this. But I do not know how I do that now. Anyone has a tip for me?
def split_pairs(text):
result = []
if text is None or not text:
return []
pair = ""
for i in range(len(text)):
if i % 2 == 0:
pair += text[i]
pair += text[i+1]
else:
result.append(pair)
return result
You could use a list comprehension to zip together the even values with the corresponding odd values. And using itertools.zip_longest you can use the fillvalue argument to provide a "fill in" if there is a length mismatch.
>>> from itertools import zip_longest
>>> s = 'abcde'
>>> pairs = [i+j for i,j in zip_longest(s[::2], s[1::2], fillvalue='_')]
>>> pairs
['ab', 'cd', 'e_']
You should reset your "pair" variable once appended to "result"
def split_pairs(text):
result = []
if text is None or not text:
return []
pair = ""
for i in range(len(text)):
if i % 2 == 0:
pair += text[i]
pair += text[i+1]
else:
result.append(pair)
pair = ""
return result
You could also use a list comprehension over a range with 3rd step parameter and add ljust to add _. This will also work nicely for more than just pairs:
>>> s = "abcde"
>>> k = 2
>>> [s[i:i+k].ljust(k, "_") for i in range(0, len(s), k)]
['ab', 'cd', 'e_']
I am not if your code needed to be in the format you originally wrote it in, but I wrote the below code that gets the job done.
def split_pairs(text):
if len(text) % 2 == 0:
result = [text[i:i+2] for i in range(0, len(text), 2)]
else:
result = [text[i:i+2] for i in range(0, len(text), 2)]
result[-1]+="_"
return result
The issue here is that the "pair" variable is never reinitialized to "".
Make sure you make it an empty string in your else block.
def split_pairs(text):
result = []
if text is None or not text:
return []
pair = ""
for i in range(len(text)):
if i % 2 == 0:
pair += text[i]
pair += text[i+1]
else:
result.append(pair)
pair = "" # Make sure you reset it
return result
If you want to have a "_" at the end (in case of an odd number of character), you could do like the following:
def split_pairs(text):
result = []
if text is None or not text:
return []
pair = "__" # Setting pair to "__" by default
for i in range(len(text)):
if i % 2 == 0:
pair[0] = text[i]
if i < len(text): # Avoiding overflow
pair[1] = text[i+1]
else:
result.append(pair)
pair = "__" # Make sure you reset it
if pair != "__": # Last bit
result.append(pair)
return result
(sorry for bad title I had trouble sumerizing)So I'm working on a project where a have to take a list of completely random numbers, find the sum of digits in each number, and place that sum in a list. Here is what I have so far:
import random
import math
list1 = [random.randint(1,1000000000000) for i in range(0,10)]
list2 = []
list3 = []
def open_command():
for y in range(0,10):
a = list1[y]
z = len(str(a))
for x in range(0, z):
f = len(str(a))
b = a*0.1
c, w=(math.modf(b))
d = int(c*10)
list2.append(d)
a = (a - d)/10
if f == 0:
total = sum(list2)
list3.append(total)
list2.clear()
open_command()
print(list3)
When I run this code the list3 just displays an empty list however there is no error. I don't understand, Is the .append not working? Can somebody explain what is going on?
Using map, One liner
list_num = [123,456]
print([sum(list(map(int, list(str(num))))) for num in list_num])
Output:
[6, 15]
That comes because the following code never got executed. List 3 is never appended and the list 2 never gots clear.
if f == 0:
total = sum(list2)
list3.append(total)
list2.clear()
You never change a, so the length of it (f) never becomes 0. Therefore, you never append anything.
But you're overcomplicating things:
list3 = [sum(int(char) for char in str(num)) for num in list1]
Or, if you want to keep your basic concept:
def open_command():
for number in list1:
for char in str(number):
list2.append(int(char))
list3.append(sum(list2))
list2.clear()
return list3
I need to figure out a way to delete common characters from two strings if the common characters are in the same position, but it is not working and I am trying to figure this out. This is what I tried so far, it works for some strings, but as soon as the second string is larger than the first, it stops working. EDIT: I also need a way to store the result in a variable before printing it as I need to use it in another function.
Example :
ABCDEF and ABLDKG would result in the "ABD" parts of both strings to be deleted, but the rest of the string would remain the same
CEF and LKG would be the output
def compare(input1,input2):
if len(input1) < len(input2):
for i in input1:
posi = int(input1.find(i))
if input1[num] == input2[num]:
x = input1.replace(i,"" )
y = input2.replace(i,"" )
num = num+1
print(x)
print(y)
else:
for i in input2:
num = 0
posi = int(input2.find(i))
if input2[num] == input1[num]:
input1 = input1[0:num] + input1[num+1:(len(input1)+ 1 )] # input1.replace(i,"" )
input2 = input2[0:num] + input2[num+1:(len(input1) + 1)]
x = input1
y = input2
num = num + 1
print(str(x))
print(str(y))
you could use
from itertools import zip_longest
a,b = "ABCDEF","ABLDKG"
[''.join(k) for k in zip(*[i for i in zip_longest(a, b, fillvalue = "") if i[0]!=i[1]])]
['CEF', 'LKG']
You can wrap this in a function:
def compare(a, b):
s = zip(*[i for i in zip_longest(a, b, fillvalue = "") if i[0]!=i[1]])
return [''.join(k) for k in s]
compare("ABCDEF","ABLDKG")
['CEF', 'LKG']
compare('asdfq', 'aqdexyz')
['sfq', 'qexyz']
strlist = ["ABCDEF","ABLDKG"]
char_dict = dict()
for item in strlist:
for char in item:
char_dict[char] = char_dict.get(char,0) + 1
new_strlist = []
for item in strlist:
new_strlist.append(''.join([char for char in item if char_dict[char] < 2]))
Note that this will convert strings that have only duplicates into empty strings rather than removing them altogether.
I have no idea how to use put these results into a list and sort it using python3.
def get_new(x):
i = 0
while i < 6:
i = i+1
print (x)
x = (x*31334)%31337
get_new(7546)
One way to do this is to create a list and append the values of x. Then return this list from your function:
def get_new(x):
lst = []
i = 0
while i < 6:
i = i+1
x = (x*31334)%31337
lst.append(x)
return lst
print (get_new(7546))
#[8699, 5240, 15617, 15823, 15205, 17059]
For calculating and sorting the calculated list, do this using list append and sort.
def get_new(x):
new_list = []
i = 0
while i < 6:
i = i+1
#print (x)
x = (x*31334)%31337
new_list.append(x) # append the each new value of x to `new_list`
return new_list
a = get_new(7546) # returns the unsorted calculated list
a.sort() # sorting using sort() function
print (a)
#OUTPUT [5240, 8699, 15205, 15617, 15823, 17059]
I have a max length of a list item that I need to enforce. How would I accomplish the following:
MAX_LENGTH = 13
>>> str(["hello","david"])[:MAX_LENGTH]
"['hello', 'da"
==> ["hello", "da"]
I was thinking using ast.literal_eval, but was wondering what might be recommended here.
I would caution against this. There has to be safer things to do than this. At the very least you should never be splitting elements in half. For instance:
import sys
overrun = []
data = ["Hello,"] + ( ["buffer"] * 80 )
maxsize = 800
# sys.getsizeof(data) is now 840 in my implementation.
while True:
while sys.getsizeof(data) > maxsize:
overrun.append(data.pop())
do_something_with(data)
if overrun:
data, overrun = overrun, []
else:
break
Here is a simplified version of #AdamSmith's answer which I ended up using:
import sys
from copy import copy
def limit_list_size(ls, maxsize=800):
data = copy(ls)
while (sys.getsizeof(str(data)) > maxsize):
if not data: break
data.pop()
return data
Note that this will not split mid-word. And because this is returning a copy of the data, the user can see which items were excluded in the output. For example:
old_ls = [...]
new_ls = limit_list_size(old_ls)
overflow_ls = list(set(old_ls) - set(new_ls))
If you want MAX_LENGTH of your strings concatenated, you could do it with a loop pretty simply, using something like this:
def truncateStringList(myArray)
currentLength = 0
result = []
for string in myArray:
if (currentLength + len(string)) > MAX_LENGTH:
result.append(string[:len(string) + currentLength - MAX_LENGTH])
return result
else:
result.append(string)
return result
If you want it of the string representation, you are effectively adding 2 chars at the beginning of each element, [' or ', and two at the end, ', or '], so add 2 to current length before and after each element in the loop:
for string in myArray:
currentLength += 2
if (currentLength + len(string)) > MAX_LENGTH:
result.append(string[:len(string) + currentLength - MAX_LENGTH])
return result
else:
result.append(string)
currentLength += 2
return result
with loops:
max = 11
mylist = ['awdawdwad', 'uppps']
newlist = ','.join(mylist)
print mylist
c= [x for x in newlist if not x==',']
if len(c)>max:
newlist= list(newlist)
newlist.reverse()
for x in range(len(c)-max):
if newlist[0]==',':
del newlist[0]
del newlist[0] # delete two times
else:
del newlist[0]
while newlist[0]==',':
del newlist[0]
newlist.reverse()
cappedlist = ''.join(newlist).split(',')
print cappedlist