If any two items in a list is equal to a given number











up vote
7
down vote

favorite
1












I just subscribed to the daily coding problems and received my first today.



The problem is:




Given a list of numbers and a number k, return whether any two numbers from the list add up to k. For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.




This is what I came up with:



def anyequalto(x, y):
for i in x:
if y - i in x:
return True


anyequalto([10, 15, 3, 7], 17)


I was wondering if anyone had any notes or alternatives as I'm very new to Python and programming.










share|improve this question









New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Your revised code is actually less efficient. There is no point in creating a new list each time.
    – Solomon Ucko
    10 hours ago










  • This puzzle must be making the rounds, because someone posted it on this site a few days ago: codereview.stackexchange.com/questions/208138/…
    – Eric Lippert
    7 hours ago






  • 4




    Please do not add new code to your question. Your new code has a few aspects that deserve to be reviewed. You can do so in a different follow-up question. Please refer to the rules for that.
    – Josay
    7 hours ago






  • 1




    Your revised code doesn't work correctly with duplicate values. contains_pair_totalling([5, 5], 10) returns false. Sets don't contain duplicates, so your remove call breaks this case.
    – jaxad0127
    7 hours ago






  • 1




    The original code didn’t work with the sum double any list value, either. anyequalto([5], 10) returns True!
    – AJNeufeld
    7 hours ago















up vote
7
down vote

favorite
1












I just subscribed to the daily coding problems and received my first today.



The problem is:




Given a list of numbers and a number k, return whether any two numbers from the list add up to k. For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.




This is what I came up with:



def anyequalto(x, y):
for i in x:
if y - i in x:
return True


anyequalto([10, 15, 3, 7], 17)


I was wondering if anyone had any notes or alternatives as I'm very new to Python and programming.










share|improve this question









New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Your revised code is actually less efficient. There is no point in creating a new list each time.
    – Solomon Ucko
    10 hours ago










  • This puzzle must be making the rounds, because someone posted it on this site a few days ago: codereview.stackexchange.com/questions/208138/…
    – Eric Lippert
    7 hours ago






  • 4




    Please do not add new code to your question. Your new code has a few aspects that deserve to be reviewed. You can do so in a different follow-up question. Please refer to the rules for that.
    – Josay
    7 hours ago






  • 1




    Your revised code doesn't work correctly with duplicate values. contains_pair_totalling([5, 5], 10) returns false. Sets don't contain duplicates, so your remove call breaks this case.
    – jaxad0127
    7 hours ago






  • 1




    The original code didn’t work with the sum double any list value, either. anyequalto([5], 10) returns True!
    – AJNeufeld
    7 hours ago













up vote
7
down vote

favorite
1









up vote
7
down vote

favorite
1






1





I just subscribed to the daily coding problems and received my first today.



The problem is:




Given a list of numbers and a number k, return whether any two numbers from the list add up to k. For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.




This is what I came up with:



def anyequalto(x, y):
for i in x:
if y - i in x:
return True


anyequalto([10, 15, 3, 7], 17)


I was wondering if anyone had any notes or alternatives as I'm very new to Python and programming.










share|improve this question









New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I just subscribed to the daily coding problems and received my first today.



The problem is:




Given a list of numbers and a number k, return whether any two numbers from the list add up to k. For example, given [10, 15, 3, 7] and k of 17, return true since 10 + 7 is 17.




This is what I came up with:



def anyequalto(x, y):
for i in x:
if y - i in x:
return True


anyequalto([10, 15, 3, 7], 17)


I was wondering if anyone had any notes or alternatives as I'm very new to Python and programming.







python






share|improve this question









New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 29 mins ago









Jamal

30.2k11115226




30.2k11115226






New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 12 hours ago









SimonJ

362




362




New contributor




SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






SimonJ is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • Your revised code is actually less efficient. There is no point in creating a new list each time.
    – Solomon Ucko
    10 hours ago










  • This puzzle must be making the rounds, because someone posted it on this site a few days ago: codereview.stackexchange.com/questions/208138/…
    – Eric Lippert
    7 hours ago






  • 4




    Please do not add new code to your question. Your new code has a few aspects that deserve to be reviewed. You can do so in a different follow-up question. Please refer to the rules for that.
    – Josay
    7 hours ago






  • 1




    Your revised code doesn't work correctly with duplicate values. contains_pair_totalling([5, 5], 10) returns false. Sets don't contain duplicates, so your remove call breaks this case.
    – jaxad0127
    7 hours ago






  • 1




    The original code didn’t work with the sum double any list value, either. anyequalto([5], 10) returns True!
    – AJNeufeld
    7 hours ago


















  • Your revised code is actually less efficient. There is no point in creating a new list each time.
    – Solomon Ucko
    10 hours ago










  • This puzzle must be making the rounds, because someone posted it on this site a few days ago: codereview.stackexchange.com/questions/208138/…
    – Eric Lippert
    7 hours ago






  • 4




    Please do not add new code to your question. Your new code has a few aspects that deserve to be reviewed. You can do so in a different follow-up question. Please refer to the rules for that.
    – Josay
    7 hours ago






  • 1




    Your revised code doesn't work correctly with duplicate values. contains_pair_totalling([5, 5], 10) returns false. Sets don't contain duplicates, so your remove call breaks this case.
    – jaxad0127
    7 hours ago






  • 1




    The original code didn’t work with the sum double any list value, either. anyequalto([5], 10) returns True!
    – AJNeufeld
    7 hours ago
















Your revised code is actually less efficient. There is no point in creating a new list each time.
– Solomon Ucko
10 hours ago




Your revised code is actually less efficient. There is no point in creating a new list each time.
– Solomon Ucko
10 hours ago












This puzzle must be making the rounds, because someone posted it on this site a few days ago: codereview.stackexchange.com/questions/208138/…
– Eric Lippert
7 hours ago




This puzzle must be making the rounds, because someone posted it on this site a few days ago: codereview.stackexchange.com/questions/208138/…
– Eric Lippert
7 hours ago




4




4




Please do not add new code to your question. Your new code has a few aspects that deserve to be reviewed. You can do so in a different follow-up question. Please refer to the rules for that.
– Josay
7 hours ago




Please do not add new code to your question. Your new code has a few aspects that deserve to be reviewed. You can do so in a different follow-up question. Please refer to the rules for that.
– Josay
7 hours ago




1




1




Your revised code doesn't work correctly with duplicate values. contains_pair_totalling([5, 5], 10) returns false. Sets don't contain duplicates, so your remove call breaks this case.
– jaxad0127
7 hours ago




Your revised code doesn't work correctly with duplicate values. contains_pair_totalling([5, 5], 10) returns false. Sets don't contain duplicates, so your remove call breaks this case.
– jaxad0127
7 hours ago




1




1




The original code didn’t work with the sum double any list value, either. anyequalto([5], 10) returns True!
– AJNeufeld
7 hours ago




The original code didn’t work with the sum double any list value, either. anyequalto([5], 10) returns True!
– AJNeufeld
7 hours ago










5 Answers
5






active

oldest

votes

















up vote
7
down vote













Return value



Adding a few tests, we have:



print(anyequalto([10, 15, 3, 7], 17))
print(anyequalto([10, 15, 3, 7], 18))
print(anyequalto([10, 15, 3, 7], 19))


giving



True
True
None


The None value seems a bit unexpected to me. We'd probably want False to be returned in that particular case.



Also, even if you expect None to be returned in that case, the Python Style Guide recommends being explicit for that (emphasis is mine):




Be consistent in return statements. Either all return statements in a
function should return an expression, or none of them should. If any
return statement returns an expression, any return statements where no
value is returned should explicitly state this as return None, and an
explicit return statement should be present at the end of the function
(if reachable)
.




Names, documentation and tests



The variables names could be clearer.



Also, the function behavior can be described in a docstring.



Finally, it could be worth writing tests for it.



You'd get something like:



def anyequalto(num_lst, n):
"""Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
for i in num_lst:
if n - i in num_lst:
return True
return False

TESTS = [
# Random tests cases
([10, 15, 3, 7], 17, True),
([10, 15, 3, 7], 18, True),
([10, 15, 3, 7], 19, False),
# Edge case
(, 0, False),
(, 1, False),
# Same value
([5, 5], 10, True),
([5], 10, True),
# Zero
([5, 0], 0, True),
([5, 0], 5, True),
([5, 0], 2, False),
]

for (lst, n, expected_res) in TESTS:
res = anyequalto(lst, n)
if res != expected_res:
print("Error with ", lst, n, "got", res, "expected", expected_res)


Data structure



At the moment, you can iterate on the list (via the in check) for each element of the list. This leads to an O(n²) behavior.



You can makes t hings more efficient by building a set to perform the in test in constant time and have an overall O(n) behavior.



def anyequalto(num_lst, n):
"""Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
num_set = set(num_lst)
for i in num_set:
if n - i in num_set:
return True
return False


Using the Python toolbox



The solution you are using could be written in a more concise and efficient way using the all or any builtin.



You have something like:



def anyequalto(num_lst, n):
"""Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
num_set = set(num_lst)
return any(n - i in num_set for i in num_set)





share|improve this answer





















  • The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
    – SimonJ
    11 hours ago




















up vote
4
down vote













There's a failing case you might have missed. If the target number is exactly twice the value of one of the entries, then you'll wrongly return true.



Test case:



anyequalto([5], 10)


Besides that, try to think of a better name for the function. Perhaps contains_pair_totalling() as a start?






share|improve this answer





















  • Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
    – SimonJ
    11 hours ago


















up vote
2
down vote














  1. for a much faster way to check if a number is in some container, use a set():
    anyequalto({10, 15, 3, 7}, 17). even if you have to convert from a list first,
    it will still be faster to do that once rather than linearly search the list each
    iteration. This will make your function O(n) rather than O(n^2)


  2. choose more expressive variable names that x and y. something like
    numbers and k
    j



  3. If you want to write this in a more functional style, you could do:



    def anyequalto(numbers, k):
    numbers = set(numbers)
    return any((k-num) in numbers
    for num in numbers)


    Because any will terminate early if the generator produces a true
    value, this will be very similar in speed to an iterative solution.








share|improve this answer



















  • 1




    It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
    – Graipher
    12 hours ago










  • Actually, I think it needs to be any((k-num) in numbers for num in numbers)
    – Toby Speight
    11 hours ago


















up vote
0
down vote













Here's a fix to the edge case. We want to check explicitly that we have a valid solution, which means that we want something akin to any2 instead of any (since if we have just a single match then we have the problem case).



def anyequalto(numbers, k):
number_set = set(numbers)
solutions = [num for num in numbers
if k - num in number_set]
return len(solutions) > 1


This fixes the edge case and still retains O(n) runtime since it uses a set.



>>> anyequalto([5], 10)
False


Aside



Right now this produces a list with the list comprehension used to generate solutions which one might argue is needlessly inefficient. I couldn't think of a stylistically good way to assert that a generator has more than one element aside from checking for StopIteration which I think is kinda clunky.






share|improve this answer








New contributor




cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


















  • next(iterator, sentinel) will return sentinel if the iterator is exhausted.
    – spectras
    2 hours ago


















up vote
0
down vote













A simple solution would use any and itertools.combinations



from itertools import combinations

def anytwoequalto(numbers, k):
return any(((i + j) == k) for i, j in combinations(numbers, 2))


itertools.combinations iterates over the given object returning tuples with the given number of items in them with no repetitions. eg.



combinations('ABCD', 2) =>
(('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))


any returns True if any of the expressions ((i + j) == k) evaluate to True



If you wish to consider that an item can be added to itself, use combinations_with_replacement instead.



Note: depending on the version of Python you are using, you may need to add extra parentheses (()) around the expression inside the any call.



Hope this makes sense.






share|improve this answer








New contributor




Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


















    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    SimonJ is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208944%2fif-any-two-items-in-a-list-is-equal-to-a-given-number%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    7
    down vote













    Return value



    Adding a few tests, we have:



    print(anyequalto([10, 15, 3, 7], 17))
    print(anyequalto([10, 15, 3, 7], 18))
    print(anyequalto([10, 15, 3, 7], 19))


    giving



    True
    True
    None


    The None value seems a bit unexpected to me. We'd probably want False to be returned in that particular case.



    Also, even if you expect None to be returned in that case, the Python Style Guide recommends being explicit for that (emphasis is mine):




    Be consistent in return statements. Either all return statements in a
    function should return an expression, or none of them should. If any
    return statement returns an expression, any return statements where no
    value is returned should explicitly state this as return None, and an
    explicit return statement should be present at the end of the function
    (if reachable)
    .




    Names, documentation and tests



    The variables names could be clearer.



    Also, the function behavior can be described in a docstring.



    Finally, it could be worth writing tests for it.



    You'd get something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    for i in num_lst:
    if n - i in num_lst:
    return True
    return False

    TESTS = [
    # Random tests cases
    ([10, 15, 3, 7], 17, True),
    ([10, 15, 3, 7], 18, True),
    ([10, 15, 3, 7], 19, False),
    # Edge case
    (, 0, False),
    (, 1, False),
    # Same value
    ([5, 5], 10, True),
    ([5], 10, True),
    # Zero
    ([5, 0], 0, True),
    ([5, 0], 5, True),
    ([5, 0], 2, False),
    ]

    for (lst, n, expected_res) in TESTS:
    res = anyequalto(lst, n)
    if res != expected_res:
    print("Error with ", lst, n, "got", res, "expected", expected_res)


    Data structure



    At the moment, you can iterate on the list (via the in check) for each element of the list. This leads to an O(n²) behavior.



    You can makes t hings more efficient by building a set to perform the in test in constant time and have an overall O(n) behavior.



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    for i in num_set:
    if n - i in num_set:
    return True
    return False


    Using the Python toolbox



    The solution you are using could be written in a more concise and efficient way using the all or any builtin.



    You have something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    return any(n - i in num_set for i in num_set)





    share|improve this answer





















    • The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
      – SimonJ
      11 hours ago

















    up vote
    7
    down vote













    Return value



    Adding a few tests, we have:



    print(anyequalto([10, 15, 3, 7], 17))
    print(anyequalto([10, 15, 3, 7], 18))
    print(anyequalto([10, 15, 3, 7], 19))


    giving



    True
    True
    None


    The None value seems a bit unexpected to me. We'd probably want False to be returned in that particular case.



    Also, even if you expect None to be returned in that case, the Python Style Guide recommends being explicit for that (emphasis is mine):




    Be consistent in return statements. Either all return statements in a
    function should return an expression, or none of them should. If any
    return statement returns an expression, any return statements where no
    value is returned should explicitly state this as return None, and an
    explicit return statement should be present at the end of the function
    (if reachable)
    .




    Names, documentation and tests



    The variables names could be clearer.



    Also, the function behavior can be described in a docstring.



    Finally, it could be worth writing tests for it.



    You'd get something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    for i in num_lst:
    if n - i in num_lst:
    return True
    return False

    TESTS = [
    # Random tests cases
    ([10, 15, 3, 7], 17, True),
    ([10, 15, 3, 7], 18, True),
    ([10, 15, 3, 7], 19, False),
    # Edge case
    (, 0, False),
    (, 1, False),
    # Same value
    ([5, 5], 10, True),
    ([5], 10, True),
    # Zero
    ([5, 0], 0, True),
    ([5, 0], 5, True),
    ([5, 0], 2, False),
    ]

    for (lst, n, expected_res) in TESTS:
    res = anyequalto(lst, n)
    if res != expected_res:
    print("Error with ", lst, n, "got", res, "expected", expected_res)


    Data structure



    At the moment, you can iterate on the list (via the in check) for each element of the list. This leads to an O(n²) behavior.



    You can makes t hings more efficient by building a set to perform the in test in constant time and have an overall O(n) behavior.



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    for i in num_set:
    if n - i in num_set:
    return True
    return False


    Using the Python toolbox



    The solution you are using could be written in a more concise and efficient way using the all or any builtin.



    You have something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    return any(n - i in num_set for i in num_set)





    share|improve this answer





















    • The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
      – SimonJ
      11 hours ago















    up vote
    7
    down vote










    up vote
    7
    down vote









    Return value



    Adding a few tests, we have:



    print(anyequalto([10, 15, 3, 7], 17))
    print(anyequalto([10, 15, 3, 7], 18))
    print(anyequalto([10, 15, 3, 7], 19))


    giving



    True
    True
    None


    The None value seems a bit unexpected to me. We'd probably want False to be returned in that particular case.



    Also, even if you expect None to be returned in that case, the Python Style Guide recommends being explicit for that (emphasis is mine):




    Be consistent in return statements. Either all return statements in a
    function should return an expression, or none of them should. If any
    return statement returns an expression, any return statements where no
    value is returned should explicitly state this as return None, and an
    explicit return statement should be present at the end of the function
    (if reachable)
    .




    Names, documentation and tests



    The variables names could be clearer.



    Also, the function behavior can be described in a docstring.



    Finally, it could be worth writing tests for it.



    You'd get something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    for i in num_lst:
    if n - i in num_lst:
    return True
    return False

    TESTS = [
    # Random tests cases
    ([10, 15, 3, 7], 17, True),
    ([10, 15, 3, 7], 18, True),
    ([10, 15, 3, 7], 19, False),
    # Edge case
    (, 0, False),
    (, 1, False),
    # Same value
    ([5, 5], 10, True),
    ([5], 10, True),
    # Zero
    ([5, 0], 0, True),
    ([5, 0], 5, True),
    ([5, 0], 2, False),
    ]

    for (lst, n, expected_res) in TESTS:
    res = anyequalto(lst, n)
    if res != expected_res:
    print("Error with ", lst, n, "got", res, "expected", expected_res)


    Data structure



    At the moment, you can iterate on the list (via the in check) for each element of the list. This leads to an O(n²) behavior.



    You can makes t hings more efficient by building a set to perform the in test in constant time and have an overall O(n) behavior.



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    for i in num_set:
    if n - i in num_set:
    return True
    return False


    Using the Python toolbox



    The solution you are using could be written in a more concise and efficient way using the all or any builtin.



    You have something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    return any(n - i in num_set for i in num_set)





    share|improve this answer












    Return value



    Adding a few tests, we have:



    print(anyequalto([10, 15, 3, 7], 17))
    print(anyequalto([10, 15, 3, 7], 18))
    print(anyequalto([10, 15, 3, 7], 19))


    giving



    True
    True
    None


    The None value seems a bit unexpected to me. We'd probably want False to be returned in that particular case.



    Also, even if you expect None to be returned in that case, the Python Style Guide recommends being explicit for that (emphasis is mine):




    Be consistent in return statements. Either all return statements in a
    function should return an expression, or none of them should. If any
    return statement returns an expression, any return statements where no
    value is returned should explicitly state this as return None, and an
    explicit return statement should be present at the end of the function
    (if reachable)
    .




    Names, documentation and tests



    The variables names could be clearer.



    Also, the function behavior can be described in a docstring.



    Finally, it could be worth writing tests for it.



    You'd get something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    for i in num_lst:
    if n - i in num_lst:
    return True
    return False

    TESTS = [
    # Random tests cases
    ([10, 15, 3, 7], 17, True),
    ([10, 15, 3, 7], 18, True),
    ([10, 15, 3, 7], 19, False),
    # Edge case
    (, 0, False),
    (, 1, False),
    # Same value
    ([5, 5], 10, True),
    ([5], 10, True),
    # Zero
    ([5, 0], 0, True),
    ([5, 0], 5, True),
    ([5, 0], 2, False),
    ]

    for (lst, n, expected_res) in TESTS:
    res = anyequalto(lst, n)
    if res != expected_res:
    print("Error with ", lst, n, "got", res, "expected", expected_res)


    Data structure



    At the moment, you can iterate on the list (via the in check) for each element of the list. This leads to an O(n²) behavior.



    You can makes t hings more efficient by building a set to perform the in test in constant time and have an overall O(n) behavior.



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    for i in num_set:
    if n - i in num_set:
    return True
    return False


    Using the Python toolbox



    The solution you are using could be written in a more concise and efficient way using the all or any builtin.



    You have something like:



    def anyequalto(num_lst, n):
    """Return True if 2 numbers from `num_lst` add up to n, False otherwise."""
    num_set = set(num_lst)
    return any(n - i in num_set for i in num_set)






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 12 hours ago









    Josay

    24.6k13783




    24.6k13783












    • The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
      – SimonJ
      11 hours ago




















    • The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
      – SimonJ
      11 hours ago


















    The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
    – SimonJ
    11 hours ago






    The any builtin is something I hadn't seen yet. Since someone pointed out that if the value of n is the exact double of an item in num_lst. How would that work out with any? If possible.
    – SimonJ
    11 hours ago














    up vote
    4
    down vote













    There's a failing case you might have missed. If the target number is exactly twice the value of one of the entries, then you'll wrongly return true.



    Test case:



    anyequalto([5], 10)


    Besides that, try to think of a better name for the function. Perhaps contains_pair_totalling() as a start?






    share|improve this answer





















    • Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
      – SimonJ
      11 hours ago















    up vote
    4
    down vote













    There's a failing case you might have missed. If the target number is exactly twice the value of one of the entries, then you'll wrongly return true.



    Test case:



    anyequalto([5], 10)


    Besides that, try to think of a better name for the function. Perhaps contains_pair_totalling() as a start?






    share|improve this answer





















    • Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
      – SimonJ
      11 hours ago













    up vote
    4
    down vote










    up vote
    4
    down vote









    There's a failing case you might have missed. If the target number is exactly twice the value of one of the entries, then you'll wrongly return true.



    Test case:



    anyequalto([5], 10)


    Besides that, try to think of a better name for the function. Perhaps contains_pair_totalling() as a start?






    share|improve this answer












    There's a failing case you might have missed. If the target number is exactly twice the value of one of the entries, then you'll wrongly return true.



    Test case:



    anyequalto([5], 10)


    Besides that, try to think of a better name for the function. Perhaps contains_pair_totalling() as a start?







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 11 hours ago









    Toby Speight

    22.7k537109




    22.7k537109












    • Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
      – SimonJ
      11 hours ago


















    • Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
      – SimonJ
      11 hours ago
















    Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
    – SimonJ
    11 hours ago




    Didn't think of that. I'd fix this by taking the number it's checking out of the list, then checking it and adding it back for the next run. Any thoughts?
    – SimonJ
    11 hours ago










    up vote
    2
    down vote














    1. for a much faster way to check if a number is in some container, use a set():
      anyequalto({10, 15, 3, 7}, 17). even if you have to convert from a list first,
      it will still be faster to do that once rather than linearly search the list each
      iteration. This will make your function O(n) rather than O(n^2)


    2. choose more expressive variable names that x and y. something like
      numbers and k
      j



    3. If you want to write this in a more functional style, you could do:



      def anyequalto(numbers, k):
      numbers = set(numbers)
      return any((k-num) in numbers
      for num in numbers)


      Because any will terminate early if the generator produces a true
      value, this will be very similar in speed to an iterative solution.








    share|improve this answer



















    • 1




      It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
      – Graipher
      12 hours ago










    • Actually, I think it needs to be any((k-num) in numbers for num in numbers)
      – Toby Speight
      11 hours ago















    up vote
    2
    down vote














    1. for a much faster way to check if a number is in some container, use a set():
      anyequalto({10, 15, 3, 7}, 17). even if you have to convert from a list first,
      it will still be faster to do that once rather than linearly search the list each
      iteration. This will make your function O(n) rather than O(n^2)


    2. choose more expressive variable names that x and y. something like
      numbers and k
      j



    3. If you want to write this in a more functional style, you could do:



      def anyequalto(numbers, k):
      numbers = set(numbers)
      return any((k-num) in numbers
      for num in numbers)


      Because any will terminate early if the generator produces a true
      value, this will be very similar in speed to an iterative solution.








    share|improve this answer



















    • 1




      It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
      – Graipher
      12 hours ago










    • Actually, I think it needs to be any((k-num) in numbers for num in numbers)
      – Toby Speight
      11 hours ago













    up vote
    2
    down vote










    up vote
    2
    down vote










    1. for a much faster way to check if a number is in some container, use a set():
      anyequalto({10, 15, 3, 7}, 17). even if you have to convert from a list first,
      it will still be faster to do that once rather than linearly search the list each
      iteration. This will make your function O(n) rather than O(n^2)


    2. choose more expressive variable names that x and y. something like
      numbers and k
      j



    3. If you want to write this in a more functional style, you could do:



      def anyequalto(numbers, k):
      numbers = set(numbers)
      return any((k-num) in numbers
      for num in numbers)


      Because any will terminate early if the generator produces a true
      value, this will be very similar in speed to an iterative solution.








    share|improve this answer















    1. for a much faster way to check if a number is in some container, use a set():
      anyequalto({10, 15, 3, 7}, 17). even if you have to convert from a list first,
      it will still be faster to do that once rather than linearly search the list each
      iteration. This will make your function O(n) rather than O(n^2)


    2. choose more expressive variable names that x and y. something like
      numbers and k
      j



    3. If you want to write this in a more functional style, you could do:



      def anyequalto(numbers, k):
      numbers = set(numbers)
      return any((k-num) in numbers
      for num in numbers)


      Because any will terminate early if the generator produces a true
      value, this will be very similar in speed to an iterative solution.









    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 10 hours ago

























    answered 12 hours ago









    Peter

    70212




    70212








    • 1




      It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
      – Graipher
      12 hours ago










    • Actually, I think it needs to be any((k-num) in numbers for num in numbers)
      – Toby Speight
      11 hours ago














    • 1




      It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
      – Graipher
      12 hours ago










    • Actually, I think it needs to be any((k-num) in numbers for num in numbers)
      – Toby Speight
      11 hours ago








    1




    1




    It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
    – Graipher
    12 hours ago




    It should be any(k in numbers for num in numbers), not any(for num in numbers k in numbers).
    – Graipher
    12 hours ago












    Actually, I think it needs to be any((k-num) in numbers for num in numbers)
    – Toby Speight
    11 hours ago




    Actually, I think it needs to be any((k-num) in numbers for num in numbers)
    – Toby Speight
    11 hours ago










    up vote
    0
    down vote













    Here's a fix to the edge case. We want to check explicitly that we have a valid solution, which means that we want something akin to any2 instead of any (since if we have just a single match then we have the problem case).



    def anyequalto(numbers, k):
    number_set = set(numbers)
    solutions = [num for num in numbers
    if k - num in number_set]
    return len(solutions) > 1


    This fixes the edge case and still retains O(n) runtime since it uses a set.



    >>> anyequalto([5], 10)
    False


    Aside



    Right now this produces a list with the list comprehension used to generate solutions which one might argue is needlessly inefficient. I couldn't think of a stylistically good way to assert that a generator has more than one element aside from checking for StopIteration which I think is kinda clunky.






    share|improve this answer








    New contributor




    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.


















    • next(iterator, sentinel) will return sentinel if the iterator is exhausted.
      – spectras
      2 hours ago















    up vote
    0
    down vote













    Here's a fix to the edge case. We want to check explicitly that we have a valid solution, which means that we want something akin to any2 instead of any (since if we have just a single match then we have the problem case).



    def anyequalto(numbers, k):
    number_set = set(numbers)
    solutions = [num for num in numbers
    if k - num in number_set]
    return len(solutions) > 1


    This fixes the edge case and still retains O(n) runtime since it uses a set.



    >>> anyequalto([5], 10)
    False


    Aside



    Right now this produces a list with the list comprehension used to generate solutions which one might argue is needlessly inefficient. I couldn't think of a stylistically good way to assert that a generator has more than one element aside from checking for StopIteration which I think is kinda clunky.






    share|improve this answer








    New contributor




    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.


















    • next(iterator, sentinel) will return sentinel if the iterator is exhausted.
      – spectras
      2 hours ago













    up vote
    0
    down vote










    up vote
    0
    down vote









    Here's a fix to the edge case. We want to check explicitly that we have a valid solution, which means that we want something akin to any2 instead of any (since if we have just a single match then we have the problem case).



    def anyequalto(numbers, k):
    number_set = set(numbers)
    solutions = [num for num in numbers
    if k - num in number_set]
    return len(solutions) > 1


    This fixes the edge case and still retains O(n) runtime since it uses a set.



    >>> anyequalto([5], 10)
    False


    Aside



    Right now this produces a list with the list comprehension used to generate solutions which one might argue is needlessly inefficient. I couldn't think of a stylistically good way to assert that a generator has more than one element aside from checking for StopIteration which I think is kinda clunky.






    share|improve this answer








    New contributor




    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    Here's a fix to the edge case. We want to check explicitly that we have a valid solution, which means that we want something akin to any2 instead of any (since if we have just a single match then we have the problem case).



    def anyequalto(numbers, k):
    number_set = set(numbers)
    solutions = [num for num in numbers
    if k - num in number_set]
    return len(solutions) > 1


    This fixes the edge case and still retains O(n) runtime since it uses a set.



    >>> anyequalto([5], 10)
    False


    Aside



    Right now this produces a list with the list comprehension used to generate solutions which one might argue is needlessly inefficient. I couldn't think of a stylistically good way to assert that a generator has more than one element aside from checking for StopIteration which I think is kinda clunky.







    share|improve this answer








    New contributor




    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    share|improve this answer



    share|improve this answer






    New contributor




    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.









    answered 10 hours ago









    cole

    2214




    2214




    New contributor




    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





    New contributor





    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    cole is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.












    • next(iterator, sentinel) will return sentinel if the iterator is exhausted.
      – spectras
      2 hours ago


















    • next(iterator, sentinel) will return sentinel if the iterator is exhausted.
      – spectras
      2 hours ago
















    next(iterator, sentinel) will return sentinel if the iterator is exhausted.
    – spectras
    2 hours ago




    next(iterator, sentinel) will return sentinel if the iterator is exhausted.
    – spectras
    2 hours ago










    up vote
    0
    down vote













    A simple solution would use any and itertools.combinations



    from itertools import combinations

    def anytwoequalto(numbers, k):
    return any(((i + j) == k) for i, j in combinations(numbers, 2))


    itertools.combinations iterates over the given object returning tuples with the given number of items in them with no repetitions. eg.



    combinations('ABCD', 2) =>
    (('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))


    any returns True if any of the expressions ((i + j) == k) evaluate to True



    If you wish to consider that an item can be added to itself, use combinations_with_replacement instead.



    Note: depending on the version of Python you are using, you may need to add extra parentheses (()) around the expression inside the any call.



    Hope this makes sense.






    share|improve this answer








    New contributor




    Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      0
      down vote













      A simple solution would use any and itertools.combinations



      from itertools import combinations

      def anytwoequalto(numbers, k):
      return any(((i + j) == k) for i, j in combinations(numbers, 2))


      itertools.combinations iterates over the given object returning tuples with the given number of items in them with no repetitions. eg.



      combinations('ABCD', 2) =>
      (('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))


      any returns True if any of the expressions ((i + j) == k) evaluate to True



      If you wish to consider that an item can be added to itself, use combinations_with_replacement instead.



      Note: depending on the version of Python you are using, you may need to add extra parentheses (()) around the expression inside the any call.



      Hope this makes sense.






      share|improve this answer








      New contributor




      Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




















        up vote
        0
        down vote










        up vote
        0
        down vote









        A simple solution would use any and itertools.combinations



        from itertools import combinations

        def anytwoequalto(numbers, k):
        return any(((i + j) == k) for i, j in combinations(numbers, 2))


        itertools.combinations iterates over the given object returning tuples with the given number of items in them with no repetitions. eg.



        combinations('ABCD', 2) =>
        (('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))


        any returns True if any of the expressions ((i + j) == k) evaluate to True



        If you wish to consider that an item can be added to itself, use combinations_with_replacement instead.



        Note: depending on the version of Python you are using, you may need to add extra parentheses (()) around the expression inside the any call.



        Hope this makes sense.






        share|improve this answer








        New contributor




        Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        A simple solution would use any and itertools.combinations



        from itertools import combinations

        def anytwoequalto(numbers, k):
        return any(((i + j) == k) for i, j in combinations(numbers, 2))


        itertools.combinations iterates over the given object returning tuples with the given number of items in them with no repetitions. eg.



        combinations('ABCD', 2) =>
        (('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D'))


        any returns True if any of the expressions ((i + j) == k) evaluate to True



        If you wish to consider that an item can be added to itself, use combinations_with_replacement instead.



        Note: depending on the version of Python you are using, you may need to add extra parentheses (()) around the expression inside the any call.



        Hope this makes sense.







        share|improve this answer








        New contributor




        Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer






        New contributor




        Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 1 hour ago









        Ben Jaguar Marshall

        1011




        1011




        New contributor




        Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        Ben Jaguar Marshall is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






















            SimonJ is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            SimonJ is a new contributor. Be nice, and check out our Code of Conduct.













            SimonJ is a new contributor. Be nice, and check out our Code of Conduct.












            SimonJ is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208944%2fif-any-two-items-in-a-list-is-equal-to-a-given-number%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

            Mangá

             ⁒  ․,‪⁊‑⁙ ⁖, ⁇‒※‌, †,⁖‗‌⁝    ‾‸⁘,‖⁔⁣,⁂‾
”‑,‥–,‬ ,⁀‹⁋‴⁑ ‒ ,‴⁋”‼ ⁨,‷⁔„ ‰′,‐‚ ‥‡‎“‷⁃⁨⁅⁣,⁔
⁇‘⁔⁡⁏⁌⁡‿‶‏⁨ ⁣⁕⁖⁨⁩⁥‽⁀  ‴‬⁜‟ ⁃‣‧⁕‮ …‍⁨‴ ⁩,⁚⁖‫ ,‵ ⁀,‮⁝‣‣ ⁑  ⁂– ․, ‾‽ ‏⁁“⁗‸ ‾… ‹‡⁌⁎‸‘ ‡⁏⁌‪ ‵⁛ ‎⁨ ―⁦⁤⁄⁕