Why won't my list.append() not append despite working in print output - list

Below is my code for the leet code problem: here
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
tripletsList = []
uniqueNums = set(nums)
uniqueNums = list(nums)
for x in range(len(uniqueNums)):
for y in range(len(uniqueNums)):
for z in range(len(uniqueNums)):
print(uniqueNums[x],uniqueNums[y],uniqueNums[z])
if (uniqueNums[x] + uniqueNums[y] + uniqueNums[z]) == 0:
if [[uniqueNums[x],uniqueNums[y],uniqueNums[z]]] not in tripletsList:
tripletsList.append([uniqueNums[x],uniqueNums[y],uniqueNums[z]])
print(tripletsList)
I realize it isn't the optimal solution but in my print line the output shows the correct combination, yet my final triplets list is not eliminating anything which leads me to believe I am not using the "not in" function of python correctly. Any help is greatly appreciated and I must be missing something that is just trivial
I tried first printing every combination of the unique list (yes tons of overlap), then I tried limiting the triplets that made it pass the == 0 check to only triplets that were not already in the triplets list (failed)

Related

Python loop query and issue

I'm new to Python so patience may be required on your behalf :) If this is not the right area for this then please let me know. I'm having trouble with a for loop navigating through a list. The idea here is to print "True" when a consecutive set of numbers are found in the list however it shouldn't print true if the sequence contains less than 3 consecutive iterations.
For example:
Ideally the program would say "You have 3 sequences in your list". In this case it would be (1,2,3), (10,11,12) and (22,23,24). Notice there are 2 other consecutive sets of numbers in the list (7,8) and (15,16) however the program should ignore them because it's less than 3 (as mentioned above). Please find code below however I'm at a slight road block. Appreciate any pointers you may have.
list1=[1,2,3,7,8,10,11,12,15,16,22,23,24]
for i in range(len(list1)-1):
if (list1[i] + 1 == list1[i+1]):
count+=1
if count >=3:
print("True")
else:
continue
continue
print(count)
I'm sure I have read the answer in similar posts but I would like to understand the code I'm missing rather than inserting code that doesn't make sense to me.
Thanks
As the query is to have only unique numbers in the sequences .. so below code will just work fine...
list1=[1,2,3,4,5,6,7,8,9,10]
count=0
i=0
while i < (len(list1)-3):
if list1[i]+1 == list1[i+1]:
if list1[i+1]+1 == list1[i+2]:
print(list1[i], list1[i+1], list1[i+2])
i=i+2
count=count+1
i=i+1
print(count)

What's slowing down this piece of python code?

I have been trying to implement the Stupid Backoff language model (the description is available here, though I believe the details are not relevant to the question).
The thing is, the code's working and producing the result that is expected, but works slower than I expected. I figured out the part that was slowing down everything is here (and NOT in the training part):
def compute_score(self, sentence):
length = len(sentence)
assert length <= self.n
if length == 1:
word = tuple(sentence)
return float(self.ngrams[length][word]) / self.total_words
else:
words = tuple(sentence[::-1])
count = self.ngrams[length][words]
if count == 0:
return self.alpha * self.compute_score(sentence[1:])
else:
return float(count) / self.ngrams[length - 1][words[:-1]]
def score(self, sentence):
""" Takes a list of strings as argument and returns the log-probability of the
sentence using your language model. Use whatever data you computed in train() here.
"""
output = 0.0
length = len(sentence)
for idx in range(length):
if idx < self.n - 1:
current_score = self.compute_score(sentence[:idx+1])
else:
current_score = self.compute_score(sentence[idx-self.n+1:idx+1])
output += math.log(current_score)
return output
self.ngrams is a nested dictionary that has n entries. Each of these entries is a dictionary of form (word_i, word_i-1, word_i-2.... word_i-n) : the count of this combination.
self.alpha is a constant that defines the penalty for going n-1.
self.n is the maximum length of that tuple that the program is looking for in the dictionary self.ngrams. It is set to 3 (though setting it to 2 or even 1 doesn't anything). It's weird because the Unigram and Bigram models work just fine in fractions of a second.
The answer that I am looking for is not a refactored version of my own code, but rather a tip which part of it is the most computationally expensive (so that I could figure out myself how to rewrite it and get the most educational profit from solving this problem).
Please, be patient, I am but a beginner (two months into the world of programming). Thanks.
UPD:
I timed the running time with the same data using time.time():
Unigram = 1.9
Bigram = 3.2
Stupid Backoff (n=2) = 15.3
Stupid Backoff (n=3) = 21.6
(It's on some bigger data than originally because of time.time's bad precision.)
If the sentence is very long, most of the code that's actually running is here:
def score(self, sentence):
for idx in range(len(sentence)): # should use xrange in Python 2!
self.compute_score(sentence[idx-self.n+1:idx+1])
def compute_score(self, sentence):
words = tuple(sentence[::-1])
count = self.ngrams[len(sentence)][words]
if count == 0:
self.compute_score(sentence[1:])
else:
self.ngrams[len(sentence) - 1][words[:-1]]
That's not meant to be working code--it just removes the unimportant parts.
The flow in the critical path is therefore:
For each word in the sentence:
Call compute_score() on that word plus the following 2. This creates a new list of length 3. You could avoid that with itertools.islice().
Construct a 3-tuple with the words reversed. This creates a new tuple. You could avoid that by passing the -1 step argument when making the slice outside this function.
Look up in self.ngrams, a nested dict, with the first key being a number (might be faster if this level were a list; there are only three keys anyway?), and the second being the tuple just created.
Recurse with the first word removed, i.e. make a new tuple (sentence[2], sentence[1]), or
Do another lookup in self.ngrams, implicitly creating another new tuple (words[:-1]).
In summary, I think the biggest problem you have is the repeated and nested creation and destruction of lists and tuples.

Python CodeChef NZEC error

Problem link
For this problem on codechef I am getting NZEC error for my python code. I new to python and I am not sure why I am getting this error.
The link to the problem is given or it can be also found under: practice -> beginner -> Nothing In Common
My Code is:
def count_c():
m=int(raw_input())
n=int(raw_input())
a = list()
b = list()
for _ in range(m):
a.append(int(raw_input()))
for _ in range(n):
b.append(int(raw_input()))
return len(list(set(a)&set(b)))
t=int(raw_input())
for _ in range(t):
print(count_c())
What you're trying to do is get m and n using separate input statements. Since you want space separated input, you might want to use:
m, n = raw_input().split(" ")
for taking multiple inputs, use a list instead of multiple variables.
For example, for accepting m values, use:
a = raw_input().split(" ")
'a' will be a list with whatever number of values in the line provided.

IndexError: list index out of range for list of lists in for loop

I've looked at the other questions posted on the site about index error, but I'm still not understanding how to fix my own code. Im a beginner when it comes to Python. Based on the users input, I want to check if that input lies in the fourth position of each line in the list of lists.
Here's the code:
#create a list of lists from the missionPlan.txt
from __future__ import with_statement
listoflists = []
with open("missionPlan.txt", "r") as f:
results = [elem for elem in f.read().split('\n') if elem]
for result in results:
listoflists.append(result.split())
#print(listoflists)
#print(listoflists[2][3])
choice = int(input('Which command would you like to alter: '))
i = 0
for rows in listoflists:
while i < len(listoflists):
if listoflists[i][3]==choice:
print (listoflists[i][0])
i += 1
This is the error I keep getting:
not getting inside the if statement
So, I think this is what you're trying to do - find any line in your "missionPlan.txt" where the 4th word (after splitting on whitespace) matches the number that was input, and print the first word of such lines.
If that is indeed accurate, then perhaps something along this line would be a better approach.
choice = int(input('Which command would you like to alter: '))
allrecords = []
with open("missionPlan.txt", "r") as f:
for line in f:
words = line.split()
allrecords.append(words)
try:
if len(words) > 3 and int(words[3]) == choice:
print words[0]
except ValueError:
pass
Also, if, as your tags suggest, you are using Python 3.x, I'm fairly certain the from __future__ import with_statement isn't particularly necessary...
EDIT: added a couple lines based on comments below. Now in addition to examining every line as it's read, and printing the first field from every line that has a fourth field matching the input, it gathers each line into the allrecords list, split into separate words as a list - corresponding to the original questions listoflists. This will enable further processing on the file later on in the code. Also fixed one glaring mistake - need to split line into words, not f...
Also, to answer your "I cant seem to get inside that if statement" observation - that's because you're comparing a string (listoflists[i][3]) with an integer (choice). The code above addresses both that comparison mismatch and the check for there actually being enough words in a line to do the comparison meaningfully...

Exponent disappearing when printing numbers

this is my first post to Stack Overflow. I have used it many times before but this is the first error that I have not found a solution to thus far. I am having a problem with a Python script where when I am changing an element in a list, the item replacing the element in the list drops the scientific notation aspect (i.e. E+08). Here is a snippet of the code and terminal output that is very strange to me. Thanks in advance for all help!
for i in range(0, len(EinsteinCof)):
for j in range(0, len(finalindexing)):
if i == finalindexing[j][0]:
if len(finalindexing[j]) == 3:
EinsteinFinal = float(EinsteinCof[finalindexing[j][0]]) + float(EinsteinCof[finalindexing[j][1]]) + float(EinsteinCof[finalindexing[j][2]])
print str(EinsteinFinal)
EinsteinCof[finalindexing[j][0]] = str(EinsteinFinal)
print str(EinsteinCof[finalindexing[j][0]])
Terminal Output:
4.1079763384e+13
4.1079763384 # <-- Where did e+13 go?
2269472400.0
2269472400.0
3.1777892e+12
3.1777892e+1 # <--where did e+12 go?
9.062911e+11
9.062911e+11