{"id":"strings-and-lists-split-join","slug":"split-and-join","title":"split, join and strip","text":"Text that a program reads often holds several values on one line: words in a sentence, numbers separated by commas. **`split`** cuts a string into a list of pieces. Without an argument, it cuts at spaces:\n\n```python\nsentence = \"the quick brown fox\"\nwords = sentence.split()\nprint(words)\nprint(len(words), \"words, the last is\", words[-1])\nprint(\"a,b,,c\".split(\",\"))\n```\n\n```output\n['the', 'quick', 'brown', 'fox']\n4 words, the last is fox\n['a', 'b', '', 'c']\n```\n\nWith an argument, `split` cuts at that text instead. Two commas in a row give an empty piece between them.\n\nThe pieces are always strings. Numbers on a line must go through `int`, one at a time:\n\n```python\nline = input(\"Two numbers: \")\nparts = line.split()\na = int(parts[0])\nb = int(parts[1])\nprint(\"Sum:\", a + b)\n```\n\n```input\n15 27\n```\n\n```output\nTwo numbers: 15 27\nSum: 42\n```\n\n### Joining\n\n**`join`** goes the other way: it joins a list of strings into one string. The string you call it on goes between the pieces. It looks backwards at first, but read it as \"join these, with this between them\":\n\n```python\nwords = [\"red\", \"green\", \"blue\"]\nprint(\", \".join(words))\nprint(\"\".join(words))\nprint(\" -> \".join(sorted(words)))\n```\n\n```output\nred, green, blue\nredgreenblue\nblue -> green -> red\n```\n\nEvery item must be a string: `\", \".join([1, 2])` is a `TypeError`. Turn numbers into strings first.\n\n### Stripping spaces\n\nUsers type extra spaces more often than you'd think. **`strip`** returns the string without spaces at its start and its end; the spaces in between stay:\n\n```python\nanswer = \"   yes please  \"\nprint(\"[\" + answer + \"]\")\nprint(\"[\" + answer.strip() + \"]\")\nprint(answer.strip() == \"yes please\")\n```\n\n```output\n[   yes please  ]\n[yes please]\nTrue\n```\n\n`split` and `join` together make a handy pair. `split()` without an argument ignores any number of spaces between words, so `\" \".join(text.split())` turns any messy spacing into single spaces.\n","task":"Fill in the blanks so the program splits the line into words, prints how many there are, and prints them joined with dashes:\n\n```\nWords: one two three\n3 words\none-two-three\n```\n","kind":"fill","seed":"line = input(\"Words: \")\nwords = line.[[split]]()\nprint(len(words), \"words\")\nprint([[\"-\"‖'-']].join(words))\n","solution":"line = input(\"Words: \")\nwords = line.split()\nprint(len(words), \"words\")\nprint(\"-\".join(words))\n","hints":["One method cuts a string into a list of words. The other is called on the string that goes between the words.","`line.split()` gives the list of words, and `\"-\".join(words)` joins them with dashes."],"tests":[{"name":"Test 1","stdin":"one two three\n","expect":"Words: one two three\n3 words\none-two-three","hidden":false},{"name":"Test 2","stdin":"a b\n","expect":"Words: a b\n2 words\na-b","hidden":true},{"name":"Test 3","stdin":"Python is fun to learn\n","expect":"Words: Python is fun to learn\n5 words\nPython-is-fun-to-learn","hidden":true}],"require":[],"forbid":[],"more":[{"task":"Write a program that reads lines of results until the user types an empty line. Each line has a name and then one or more scores, separated by spaces. For each line, the program prints the name and the total of the scores:\n\n```\nResults: Ada 12 15 9\nAda: 36\nResults: Linus 7 8\nLinus: 15\nResults:\n```\n","kind":"code","seed":"# Read results until an empty line.\n","solution":"# Read results until an empty line.\nwhile True:\n    line = input(\"Results: \")\n    if line == \"\":\n        break\n    parts = line.split()\n    total = 0\n    for score in parts[1:]:\n        total += int(score)\n    print(f\"{parts[0]}: {total}\")\n","hints":["`line.split()` gives a list: the name first, then the scores, all as strings.","The name is `parts[0]`, and the scores are the slice `parts[1:]`.","Add up the scores in a `for` loop, converting each with `int`, and print the name and the total."],"tests":[{"name":"Test 1","stdin":"Ada 12 15 9\nLinus 7 8\n\n","expect":"Results: Ada 12 15 9\nAda: 36\nResults: Linus 7 8\nLinus: 15\nResults:","hidden":false},{"name":"Test 2","stdin":"Grace 100\nGuido 1 2 3 4 5\nKen 0 0\n\n","expect":"Results: Grace 100\nGrace: 100\nResults: Guido 1 2 3 4 5\nGuido: 15\nResults: Ken 0 0\nKen: 0\nResults:","hidden":true},{"name":"Test 3","stdin":"\n","expect":"Results:","hidden":true}],"require":[],"forbid":[]},{"task":"Write the function `tidy(text: str) -> str`, which returns the text without spaces at its start and end, and with exactly one space between words. For example, `tidy(\"  too   many  spaces \")` returns `'too many spaces'`.\n","kind":"code","seed":"def tidy(text: str) -> str:\n    pass\n\n\nif __name__ == \"__main__\":\n    print(tidy(\"  too   many  spaces \"))\n","solution":"def tidy(text: str) -> str:\n    return \" \".join(text.split())\n\n\nif __name__ == \"__main__\":\n    print(tidy(\"  too   many  spaces \"))\n","hints":["`split()` without an argument ignores any number of spaces, including those at the start and the end.","Join the words again with a single space between them: `\" \".join(...)`."],"tests":[{"name":"tidy(\"  too   many  spaces \")","stdin":"","call":"tidy(\"  too   many  spaces \")\n","expect":"'too many spaces'","hidden":false,"returns":true},{"name":"tidy(\"already tidy\")","stdin":"","call":"tidy(\"already tidy\")\n","expect":"'already tidy'","hidden":true,"returns":true},{"name":"tidy(\"   lonely   \")","stdin":"","call":"tidy(\"   lonely   \")\n","expect":"'lonely'","hidden":true,"returns":true}],"require":[],"forbid":[]}]}