Compress Python code - list

How can I write the following loop in one line? Or is this not possible because of the if-statement?
a = listWithFancyIntegers
for i in range(len(a)):
if a[i] < 0:
a[i] = 0
else:
a[i] = 1
What I do not want to have is a list of booleans.
I have already searched the web to check if I can use something like a Lambda expression but I didn't find anything that helped me. (Or I didn't understand it :D)
Thank you for your support.

a = [0 if n < 0 else 1 for n in listWithFancyIntegers]
EDIT
I prefer the code I wrote above, but here's another way:
a = [int(n >= 0) for n in listWithFancyIntegers]
or if you prefer map to list comprehension:
a = map(lambda n: int(n >= 0), listWithFancyIntegers)

This can be done in a single line in Python
a = [0 if i < 0 else 1 for i in a]

Related

Efficient way for the following code

I saw this problem on hackerrank.com, the problem is to find a 4 letter palindrome from a given string which can be a long string also.
Constraint is as follows:
where, |s| is the length of the string and a,b,c,d are the positions of the corresponding letters in the palindrome.
I found out the solution for this, but it isn't efficient enough, as in during the processing time it gives 'time out' error. The code is as follows:
s='kkkkkkz'
n=0
c_i,c_j,c_k,c_l=0,0,0,0
for i in range(len(s)):
j=0;c_i+=1
while j>=0 and j<len(s):
c_j+=1
if j>i:
k=0
while k>=0 and k<len(s):
c_k+=1
if k>j:
l=0
while l>=0 and l<len(s):
c_l+=1
if l>k:
a=s[i]+s[j]+s[k]+s[l]
if a[0]==a[3] and a[1]==a[2]: n+=1
l+=1
k+=1
j+=1
print n
I thought of noticing the number of times each loop runs, which right now is 7,49,147 and 245.
It is still better than the techniques I followed before, but I am not able to to do better than this.
Suggestions please ?
One way is to use the following, but this will still not be efficient enough. Scores 12/40 ..
import itertools
s=WHATEVERSTRING
n=0
for a in itertools.combinations(s, 4):
n += (a[0] == a[3])*(a[1]==a[2])
print(n)
A working solution is to go down the following route: create a set of unique characters in the string, and map substring pairs to a dictionary. Then count all the occurrences of pairwise pairs.
from collections import defaultdict as di
data = [x for x in s.strip()]
chars = set(data)
sum_a = 0
for c in chars:
a = 0
b = di(int)
double_pairs = 0
for d in data:
if d == c:
sum_a += double_pairs
double_pairs += b[c]
b[c]+=a
a += 1
else:
double_pairs += b[d]
b[d] += a
print(sum_a%(10**9+7))

How many times a number in list 1 appears in list 2 without using count()

trying to write this code to see how many times the numbers in list 1 appear in the list two, can use a nested for or while loop but I came up with this it doesn't work. I don't want to use count.
list1 = [4,7,2]
list2 = [2,3,4,2,5,6,3,2,6,7,3,4]
def compare(list1, list2):
freq = ([i for i in list1 if i == num])
return
print('The number 4 occurs in list2', freq, 'times')
print('The number 7 occurs in list2', freq, 'times')
print('The number 2 occurs in list2', freq, 'times')
I'm not completely sure that I understand the question,
but this code seems to work, though if it may be slow if you need it for an interactive program.
Hope this helps!
list1 = [4,7,2]
list2 = [2,3,4,2,5,6,3,2,6,7,3,4]
occurrences = [0,0,0]
for i in range(len(list1)):
for j in list2:
if list1[i] == j:
occurrences[i]+=1
print occurrences
try this:
list1 = [4,7,2]
list2 = [2,3,4,2,5,6,3,2,6,7,3,4]
occurrences = [0,0,0]
for i in range(len(list1)):
for j in list2:
if list1[i] == j:
occurrences[i]+=1
print occurrences

List of Tuples remove error

ExpenseL is my list of tuples and I try to remove from the list starting from start to stop but I just get this error: in removeFromAtoB
expenseL.pop(i)
TypeError: 'tuple' object cannot be interpreted as an integer
Please help me!!! :)
def removeFromAtoB():
aux = copy.deepcopy(expenseL)
print(expenseL, "\n")
start = int(input("Starting point: "))
stop = int(input("Ending point: "))
j = 0
for i in expenseL:
if j >= start and j <= stop:
expenseL.pop(i)
j += 1
print(expenseL)
You're iterating over your list of tuples:
for i in expenseL
That means i will be one of those tuples. Then you try to use it in list.pop:
expenseL.pop(i)
This won't work, because list.pop expects an index. Just enumerate your list:
for index, tpl in enumerate(expenseL):
...
expenseL.pop(index)
But this breaks, too, because the indices change when you remove an element. You could circumvent that by not increasing j in that case, but the simpler way is just assigning an empty list to the slice:
def removeFromAtoB():
start = int(input("Starting point: "))
stop = int(input("Ending point: "))
expenseL[start:stop+1] = []

Loop problems Even Count

I have a beginner question. Loops are extremely hard for me to understand, so it's come to me asking for help.
I am trying to create a function to count the amount of even numbers in a user input list, with a negative at the end to show the end of the list. I know I need to use a while loop, but I am having trouble figuring out how to walk through the indexes of the input list. This is what I have so far, can anyone give me a hand?
def find_even_count(numlist):
count = 0
numlist.split()
while numlist > 0:
if numlist % 2 == 0:
count += 1
return count
numlist = raw_input("Please enter a list of numbers, with a negative at the end: ")
print find_even_count(numlist)
I used the split to separate out the indexes of the list, but I know I am doing something wrong. Can anyone point out what I am doing wrong, or point me to a good step by step explanation of what to do here?
Thank you guys so much, I know you probably have something more on your skill level to do, but appreciate the help!
You were pretty close, just a couple of corrections:
def find_even_count(numlist):
count = 0
lst = numlist.split()
for num in lst:
if int(num) % 2 == 0:
count += 1
return count
numlist = raw_input("Please enter a list of numbers, with a negative at the end: ")
print find_even_count(numlist)
I have used a for loop rather than a while loop, stored the outcome of numlist.split() to a variable (lst) and then just iterated over this.
You have a couple of problems:
You split numlist, but don't assign the resulting list to anything.
You then try to operate on numlist, which is still the string of all numbers.
You never try to convert anything to a number.
Instead, try:
def find_even_count(numlist):
count = 0
for numstr in numlist.split(): # iterate over the list
num = int(numstr) # convert each item to an integer
if num < 0:
break # stop when we hit a negative
elif num % 2 == 0:
count += 1 # increment count for even numbers
return count # return the total
Or, doing the whole thing in one line:
def find_even_count(numlist):
return sum(num % 2 for num in map(int, numlist.split()) if num > 0)
(Note: the one-liner will fail in cases where the user tries to trick you by putting more numbers after the "final" negative number, e.g. with numlist = "1 2 -1 3 4")
If you must use a while loop (which isn't really the best tool for the job), it would look like:
def find_even_count(numlist):
index = count = 0
numlist = list(map(int, numlist.split()))
while numlist[index] > 0:
if numlist[index] % 2 == 0:
count += 1
index += 1
return count

python matching list of lists

def compare_two_lists(list1,list2):
i=0
j=0
while i < len(list2) :
if i%2 == 0:
j == 0
else:
j == 1
for sublist2 in list2[i:] :
for sublist in list1[j:]:
#sublist.intersection(sublist2)
intersect = [x for x in sublist if x in sublist2]
print('from set ',sublist, len(intersect),' matched number(s): ', intersect)
i=i +1
compare_two_lists([[1,2,3,4,5],[20,30]],[[5,3,7,8,1],[20,10],[4,10,1,7,8],[30,20]])
I am trying to get list 0 and 1 of list 1 to compare appropriately list 0, 1, 2 and 3 of list 2 and return matches. The program almost works in the sense that it does return matches for the lists amongst other iterations. I cannot seem to be able to get the iteration to occur twice and return [1,3,5],[20], [1,4],[20,30]. Please help. I am going quite mad trying to understand how to space functions correctly and use loops logically!!
def compare_two_lists(list1,list2):
lRet = [] #a
for i in range(len(list2)): #b
j= i%2 #c
sublist1 = list1[j]
sublist2 = list2[i]
lRet.append([x for x in sublist1 if x in sublist2])
return lRet
compare_two_lists([[1,2,3,4,5],[20,30]],[[5,3,7,8,1],[20,10],[4,10,1,7,8],[30,20]])
This seems to do the trick. Here's an explanation (see line labels above):
a: lRet is initialised. We are doing to build up a list of lists in this variable
b: i runs through every index of list2
c: if i is even then j is zero, otherwise j is one. you had j==1 and j==0 in your code. These operators don't change any operand values. you meant j=1 etc. but this way is quicker
For explaining the rest I'll just talk through the actual iteration with your example input lists:
i = 0 (the first iteration)
j=0
sublist1 = [1,2,3,4,5]
sublist2 = [5,3,7,8,1]
intersection is [1,3,5]. we APPEND this to lRet.
thus lRet = [[1,3,5],]
i=1
j=1
sublist1 = [20,30]
sublist2 = [20,10]
the intersection is [20,]
thus lRet = [[1,3,5],[20]]
i=3
j=0
sublist1 = [1,2,3,4,5]
sublist2 = [4,10,1,7,8]
etc