[{"data":1,"prerenderedAt":1374},["ShallowReactive",2],{"/blog/learn-python-with-pj-part-2":3,"navigation-en-us":587,"banner-en-us":1014,"footer-en-us":1024,"blog-post-authors-en-us-PJ Metz":1268,"blog-related-posts-en-us-learn-python-with-pj-part-2":1284,"blog-promotions-en-us":1310,"next-steps-en-us":1364},{"id":4,"title":5,"authors":6,"body":8,"category":566,"date":567,"description":568,"extension":569,"externalUrl":570,"faq":570,"featured":571,"heroImage":572,"meta":573,"navigation":143,"path":574,"seo":575,"slug":579,"stem":580,"tags":581,"template":585,"updatedDate":570,"__hash__":586},"blogPosts/en-us/blog/learn-python-with-pj-part-2.md","Learn Python with Pj! Part 2 - Lists and loops",[7],"PJ Metz",{"type":9,"value":10,"toc":555},"minimark",[11,21,26,29,80,91,98,110,115,118,179,183,186,253,257,260,293,304,308,318,320,323,349,352,404,407,417,462,468,470,473,531,534,542,551],[12,13,14,15,20],"p",{},"We’re back with another article about my journey to learn Python. Check out the ",[16,17,19],"a",{"href":18},"/blog/learn-python-with-pj-part-1/","first article"," if you want to see what I’ve already learned. Today we’re talking about lists and loops, two important parts of all programming languages. Let’s check them out.",[22,23,25],"h2",{"id":24},"lists","Lists",[12,27,28],{},"Lists are a way to store information that can be accessed later. They are similar to arrays in other languages. A list is a named collection of other elements inside brackets that can be accessed by an index number.",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-python shiki shiki-themes github-light","#I will be using this list for all our examples, and, yes, these are some of my favorite musical acts pulled directly from my Spotify 2021 wrapped. \nfavorite_music = ['The Midnight', 'Night Tempo', 'St. Lucia'] \n","python","",[37,38,39,48],"code",{"__ignoreMap":35},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sAwPA","#I will be using this list for all our examples, and, yes, these are some of my favorite musical acts pulled directly from my Spotify 2021 wrapped. \n",[40,49,51,55,59,62,66,69,72,74,77],{"class":42,"line":50},2,[40,52,54],{"class":53},"sgsFI","favorite_music ",[40,56,58],{"class":57},"sD7c4","=",[40,60,61],{"class":53}," [",[40,63,65],{"class":64},"sYBdl","'The Midnight'",[40,67,68],{"class":53},", ",[40,70,71],{"class":64},"'Night Tempo'",[40,73,68],{"class":53},[40,75,76],{"class":64},"'St. Lucia'",[40,78,79],{"class":53},"]\n",[12,81,82,83,86,87,90],{},"In this list, each element of the list can be accessed by an index number. Like many other languages, python is zero-indexed, meaning the first element is at index 0. So favorite_music",[40,84,85],{},"0"," is “The Midnight”, favorite_music",[40,88,89],{},"1"," is “Night Tempo”, and so on.",[12,92,93,94,97],{},"Something interesting about lists in Python is that a negative 1 index number will give you the last element in the list. Negative 2 will give you the second to last, and so on. As far as I can tell, this isn’t possible in other languages: Negative 1 indices will return errors or ",[37,95,96],{},"undefined"," in arrays or lists in other languages. I imagine a scenario where we’ve just added something to a list and need to access it immediately. We could use the negative index number to access the most recently added element.",[12,99,100,101,104,105,103],{},"Python comes with several built-in methods to be used with lists. Some of them have the list passed in as an argument, some are added to the list with a ",[37,102,103],{},"."," so it can be used. These methods will change the list or return some kind of information about the list. Below are a few I found useful, but a more complete explanation of available methods is ",[16,106,109],{"href":107,"rel":108},"https://docs.python.org/3/tutorial/datastructures.html",[],"available here",[111,112,114],"h3",{"id":113},"pop",".pop()",[12,116,117],{},"Pop allows you to remove a specific element in a list as well as return it at the same time, meaning this can be set to a variable. To specify the element, use the desired index number inside the parentheses to remove it.",[30,119,121],{"className":32,"code":120,"language":34,"meta":35,"style":35},"best_synthwave = favorite_music.pop(0)\n\n#returns ‘['Night Tempo', 'St. Lucia']’\nprint(favorite_music)\n\n#returns 'The Midnight'\nprint(best_synthwave)\n",[37,122,123,139,145,151,160,165,171],{"__ignoreMap":35},[40,124,125,128,130,133,136],{"class":42,"line":43},[40,126,127],{"class":53},"best_synthwave ",[40,129,58],{"class":57},[40,131,132],{"class":53}," favorite_music.pop(",[40,134,85],{"class":135},"sYu0t",[40,137,138],{"class":53},")\n",[40,140,141],{"class":42,"line":50},[40,142,144],{"emptyLinePlaceholder":143},true,"\n",[40,146,148],{"class":42,"line":147},3,[40,149,150],{"class":46},"#returns ‘['Night Tempo', 'St. Lucia']’\n",[40,152,154,157],{"class":42,"line":153},4,[40,155,156],{"class":135},"print",[40,158,159],{"class":53},"(favorite_music)\n",[40,161,163],{"class":42,"line":162},5,[40,164,144],{"emptyLinePlaceholder":143},[40,166,168],{"class":42,"line":167},6,[40,169,170],{"class":46},"#returns 'The Midnight'\n",[40,172,174,176],{"class":42,"line":173},7,[40,175,156],{"class":135},[40,177,178],{"class":53},"(best_synthwave)\n",[111,180,182],{"id":181},"append-and-insert",".append() and .insert()",[12,184,185],{},"Append allows you to add an element to a list. Put the element in the parenthesis. The element is added to the end of the list. Insert allows you to say exactly where you would like the element inserted. The first argument is the index you would like to replace, and the second argument is the element to insert.",[30,187,189],{"className":32,"code":188,"language":34,"meta":35,"style":35},"favorite_music.append('Turnstile') \n\n#This will print ['The Midnight', 'Night Tempo', 'St. Lucia', 'Turnstile']\nprint(favorite_music)\n\nfavorite_music.insert(1, 'Kendrick Lamar')\n#This will print 'The Midnight', 'Kendrick Lamar', 'Night Tempo', 'St. Lucia', 'Turnstile'] \n#Turnstile is still there since we appended it before. \nprint(favorite_music)\n",[37,190,191,202,206,211,217,221,235,240,246],{"__ignoreMap":35},[40,192,193,196,199],{"class":42,"line":43},[40,194,195],{"class":53},"favorite_music.append(",[40,197,198],{"class":64},"'Turnstile'",[40,200,201],{"class":53},") \n",[40,203,204],{"class":42,"line":50},[40,205,144],{"emptyLinePlaceholder":143},[40,207,208],{"class":42,"line":147},[40,209,210],{"class":46},"#This will print ['The Midnight', 'Night Tempo', 'St. Lucia', 'Turnstile']\n",[40,212,213,215],{"class":42,"line":153},[40,214,156],{"class":135},[40,216,159],{"class":53},[40,218,219],{"class":42,"line":162},[40,220,144],{"emptyLinePlaceholder":143},[40,222,223,226,228,230,233],{"class":42,"line":167},[40,224,225],{"class":53},"favorite_music.insert(",[40,227,89],{"class":135},[40,229,68],{"class":53},[40,231,232],{"class":64},"'Kendrick Lamar'",[40,234,138],{"class":53},[40,236,237],{"class":42,"line":173},[40,238,239],{"class":46},"#This will print 'The Midnight', 'Kendrick Lamar', 'Night Tempo', 'St. Lucia', 'Turnstile'] \n",[40,241,243],{"class":42,"line":242},8,[40,244,245],{"class":46},"#Turnstile is still there since we appended it before. \n",[40,247,249,251],{"class":42,"line":248},9,[40,250,156],{"class":135},[40,252,159],{"class":53},[111,254,256],{"id":255},"len","len()",[12,258,259],{},"Len gets the length of the object passed into it. This is important since you can know exactly how many elements are in a list, which is useful for control flow as well as loops.",[30,261,263],{"className":32,"code":262,"language":34,"meta":35,"style":35},"length_of_music = len(favorite_music)\n\n#working with the original list will print “3”\nprint(length_of_music)\n",[37,264,265,277,281,286],{"__ignoreMap":35},[40,266,267,270,272,275],{"class":42,"line":43},[40,268,269],{"class":53},"length_of_music ",[40,271,58],{"class":57},[40,273,274],{"class":135}," len",[40,276,159],{"class":53},[40,278,279],{"class":42,"line":50},[40,280,144],{"emptyLinePlaceholder":143},[40,282,283],{"class":42,"line":147},[40,284,285],{"class":46},"#working with the original list will print “3”\n",[40,287,288,290],{"class":42,"line":153},[40,289,156],{"class":135},[40,291,292],{"class":53},"(length_of_music)\n",[12,294,295,296,68,298,300,301,103],{},"Notice that it prints how many elements are in the list, not how many indices. I have to work to make sure to keep those two ideas separate. So there are three elements in the list, but the indices are ",[40,297,85],{},[40,299,89],{},", and ",[40,302,303],{},"2",[22,305,307],{"id":306},"loops","Loops",[12,309,310,311,314,315,103],{},"Loops work very much the same way they do in other languages, but like I’ve seen with the rest of Python, the syntax is more readable and the code just looks a bit cleaner. The two main ways to use loops with Python are ",[37,312,313],{},"for"," and ",[37,316,317],{},"while",[111,319,313],{"id":313},[12,321,322],{},"For is used when you want to iterate through each element in an object. The syntax you use here creates a kind of one-time use variable that is then used in the code block in a variety of ways. Let’s say you want to print each band from the favorite_music list from before.",[30,324,326],{"className":32,"code":325,"language":34,"meta":35,"style":35},"for band in favorite_music:\n  print(band)\n\n",[37,327,328,341],{"__ignoreMap":35},[40,329,330,332,335,338],{"class":42,"line":43},[40,331,313],{"class":57},[40,333,334],{"class":53}," band ",[40,336,337],{"class":57},"in",[40,339,340],{"class":53}," favorite_music:\n",[40,342,343,346],{"class":42,"line":50},[40,344,345],{"class":135},"  print",[40,347,348],{"class":53},"(band)\n",[12,350,351],{},"This would print each band on its own line. If you call print() on favorite_music, it would print the array inside of brackets. You can perform logic inside of for loops to only return certain items. Say you want to only print bands that have “night” in the name:",[30,353,355],{"className":32,"code":354,"language":34,"meta":35,"style":35},"for band in favorite_music:\n    lower_case_band = band.lower()\n    if lower_case_band.__contains__('night'):\n      print(band)\n\n",[37,356,357,367,377,397],{"__ignoreMap":35},[40,358,359,361,363,365],{"class":42,"line":43},[40,360,313],{"class":57},[40,362,334],{"class":53},[40,364,337],{"class":57},[40,366,340],{"class":53},[40,368,369,372,374],{"class":42,"line":50},[40,370,371],{"class":53},"    lower_case_band ",[40,373,58],{"class":57},[40,375,376],{"class":53}," band.lower()\n",[40,378,379,382,385,388,391,394],{"class":42,"line":147},[40,380,381],{"class":57},"    if",[40,383,384],{"class":53}," lower_case_band.",[40,386,387],{"class":135},"__contains__",[40,389,390],{"class":53},"(",[40,392,393],{"class":64},"'night'",[40,395,396],{"class":53},"):\n",[40,398,399,402],{"class":42,"line":153},[40,400,401],{"class":135},"      print",[40,403,348],{"class":53},[12,405,406],{},"Note: I put all the strings into lower case so we could match cases. Also, I found the contains method on the internet and the example had two underscores on either side. It made my code work whereas without the underscores it did not work. Like I said in the first article, I’m new here and don’t know why it did that.",[12,408,409,413,414,416],{},[410,411,412],"strong",{},"EDIT March 7, 2022:"," According to commenter \"Glen666\" in the comments, the easier way to check if something is contained in another object is to use the ",[37,415,337],{}," operator. It would look like this:",[30,418,420],{"className":32,"code":419,"language":34,"meta":35,"style":35},"for band in favorite_music:\n  lower_case_band = band.lower()\n  if \"night\" in lower_case_band:\n    print(band)\n\n",[37,421,422,432,441,455],{"__ignoreMap":35},[40,423,424,426,428,430],{"class":42,"line":43},[40,425,313],{"class":57},[40,427,334],{"class":53},[40,429,337],{"class":57},[40,431,340],{"class":53},[40,433,434,437,439],{"class":42,"line":50},[40,435,436],{"class":53},"  lower_case_band ",[40,438,58],{"class":57},[40,440,376],{"class":53},[40,442,443,446,449,452],{"class":42,"line":147},[40,444,445],{"class":57},"  if",[40,447,448],{"class":64}," \"night\"",[40,450,451],{"class":57}," in",[40,453,454],{"class":53}," lower_case_band:\n",[40,456,457,460],{"class":42,"line":153},[40,458,459],{"class":135},"    print",[40,461,348],{"class":53},[12,463,464,465,467],{},"Thanks for catching this. I hadn't learned ",[37,466,337],{}," yet so this makes it a bit easier!",[111,469,317],{"id":317},[12,471,472],{},"While creates a loop that goes as long as certain criteria are being satisfied, usually a logic expression. If you want some code to run six times, you could use a while loop.",[30,474,476],{"className":32,"code":475,"language":34,"meta":35,"style":35},"i = 0\n#This prints the string below 6 times. \nwhile i \u003C 7:\n  print('The Midnight is my favorite band of all time.')\n  i += 1\n\n",[37,477,478,488,493,509,520],{"__ignoreMap":35},[40,479,480,483,485],{"class":42,"line":43},[40,481,482],{"class":53},"i ",[40,484,58],{"class":57},[40,486,487],{"class":135}," 0\n",[40,489,490],{"class":42,"line":50},[40,491,492],{"class":46},"#This prints the string below 6 times. \n",[40,494,495,497,500,503,506],{"class":42,"line":147},[40,496,317],{"class":57},[40,498,499],{"class":53}," i ",[40,501,502],{"class":57},"\u003C",[40,504,505],{"class":135}," 7",[40,507,508],{"class":53},":\n",[40,510,511,513,515,518],{"class":42,"line":153},[40,512,345],{"class":135},[40,514,390],{"class":53},[40,516,517],{"class":64},"'The Midnight is my favorite band of all time.'",[40,519,138],{"class":53},[40,521,522,525,528],{"class":42,"line":162},[40,523,524],{"class":53},"  i ",[40,526,527],{"class":57},"+=",[40,529,530],{"class":135}," 1\n",[12,532,533],{},"This is useful if you want code to run the whole time some circumstance is true, whether it’s a date, another process is running, or anything of the sort.",[12,535,536,538,539,541],{},[410,537,412],{}," Thanks to user \"magicolf\" in the comments! They let me know that there's an error here where it prints 7 times instead of 6. Because i is declared as ",[37,540,85],{}," first, the loop will actually print seven times. It's easy to make mistakes like this all the time, so I appreciate you letting me know, magicolf!",[12,543,544,545,550],{},"Loops are some of my favorite things to write so far. It’s like a little puzzle to figure out when you need to iterate through a list or string to make something happen at a specific time. The hardest part about loops is getting used to the logic of it. Python made this easier for me in that loops feel very natural to read. On top of that, I’m getting used to the indentation that I felt was so strange last time. I’ve spent about 30 or so hours working on it so far, and It’s starting to feel very natural. Hopefully, I can keep this up as we move on to the ",[16,546,549],{"href":547,"rel":548},"https://about.gitlab.com/blog/learn-python-with-pj-part-3/",[],"next learning modules","!",[552,553,554],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}",{"title":35,"searchDepth":50,"depth":50,"links":556},[557,562],{"id":24,"depth":50,"text":25,"children":558},[559,560,561],{"id":113,"depth":147,"text":114},{"id":181,"depth":147,"text":182},{"id":255,"depth":147,"text":256},{"id":306,"depth":50,"text":307,"children":563},[564,565],{"id":313,"depth":147,"text":313},{"id":317,"depth":147,"text":317},"engineering","2022-03-01","Follow along as our education evangelist Pj Metz learns about lists and loops in the second of this multipart series.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664962/Blog/Hero%20Images/python.jpg",{},"/en-us/blog/learn-python-with-pj-part-2",{"title":5,"description":568,"ogTitle":5,"ogDescription":568,"noIndex":571,"ogImage":572,"ogUrl":576,"ogSiteName":577,"ogType":578,"canonicalUrls":576},"https://about.gitlab.com/blog/learn-python-with-pj-part-2","https://about.gitlab.com","article","learn-python-with-pj-part-2","en-us/blog/learn-python-with-pj-part-2",[582,583,584],"careers","DevOps","growth","BlogPost","Xzh67HmHm62-C7p1U_47ljn9IMUb7PNYIYo9TdpQJIU",{"logo":588,"freeTrial":593,"sales":598,"login":603,"items":608,"search":934,"minimal":965,"duo":984,"switchNav":993,"pricingDeployment":1004},{"config":589},{"href":590,"dataGaName":591,"dataGaLocation":592},"/","gitlab logo","header",{"text":594,"config":595},"Get free trial",{"href":596,"dataGaName":597,"dataGaLocation":592},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":599,"config":600},"Request a demo",{"href":601,"dataGaName":602,"dataGaLocation":592},"/sales/?contact-topic=request-demo","sales",{"text":604,"config":605},"Sign in",{"href":606,"dataGaName":607,"dataGaLocation":592},"https://gitlab.com/users/sign_in/","sign in",[609,638,737,742,856,912],{"text":610,"config":611,"menu":613},"Platform",{"dataNavLevelOne":612},"platform",{"type":614,"columns":615},"cards",[616,622,630],{"title":610,"description":617,"link":618},"The intelligent orchestration platform for DevSecOps",{"text":619,"config":620},"Explore our Platform",{"href":621,"dataGaName":612,"dataGaLocation":592},"/platform/",{"title":623,"description":624,"link":625},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":626,"config":627},"Meet GitLab Duo",{"href":628,"dataGaName":629,"dataGaLocation":592},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":631,"description":632,"link":633},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":634,"config":635},"Learn more",{"href":636,"dataGaName":637,"dataGaLocation":592},"/why-gitlab/","why gitlab",{"text":639,"left":143,"config":640,"menu":642},"Product",{"dataNavLevelOne":641},"solutions",{"type":24,"link":643,"columns":647,"feature":716},{"text":644,"config":645},"View all Solutions",{"href":646,"dataGaName":641,"dataGaLocation":592},"/solutions/",[648,672,695],{"title":649,"description":650,"link":651,"items":656},"Automation","CI/CD and automation to accelerate deployment",{"config":652},{"icon":653,"href":654,"dataGaName":655,"dataGaLocation":592},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[657,661,664,668],{"text":658,"config":659},"CI/CD",{"href":660,"dataGaLocation":592,"dataGaName":658},"/solutions/continuous-integration/",{"text":623,"config":662},{"href":628,"dataGaLocation":592,"dataGaName":663},"gitlab duo agent platform - product menu",{"text":665,"config":666},"Source Code Management",{"href":667,"dataGaLocation":592,"dataGaName":665},"/solutions/source-code-management/",{"text":669,"config":670},"Automated Software Delivery",{"href":654,"dataGaLocation":592,"dataGaName":671},"Automated software delivery",{"title":673,"description":674,"link":675,"items":680},"Security","Deliver code faster without compromising security",{"config":676},{"href":677,"dataGaName":678,"dataGaLocation":592,"icon":679},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[681,685,690],{"text":682,"config":683},"Application Security Testing",{"href":677,"dataGaName":684,"dataGaLocation":592},"Application security testing",{"text":686,"config":687},"Software Supply Chain Security",{"href":688,"dataGaLocation":592,"dataGaName":689},"/solutions/supply-chain/","Software supply chain security",{"text":691,"config":692},"Software Compliance",{"href":693,"dataGaName":694,"dataGaLocation":592},"/solutions/software-compliance/","software compliance",{"title":696,"link":697,"items":702},"Measurement",{"config":698},{"icon":699,"href":700,"dataGaName":701,"dataGaLocation":592},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[703,707,711],{"text":704,"config":705},"Visibility & Measurement",{"href":700,"dataGaLocation":592,"dataGaName":706},"Visibility and Measurement",{"text":708,"config":709},"Value Stream Management",{"href":710,"dataGaLocation":592,"dataGaName":708},"/solutions/value-stream-management/",{"text":712,"config":713},"Analytics & Insights",{"href":714,"dataGaLocation":592,"dataGaName":715},"/solutions/analytics-and-insights/","Analytics and insights",{"title":717,"type":24,"items":718},"GitLab for",[719,725,731],{"text":720,"config":721},"Enterprise",{"icon":722,"href":723,"dataGaLocation":592,"dataGaName":724},"Building","/enterprise/","enterprise",{"text":726,"config":727},"Small Business",{"icon":728,"href":729,"dataGaLocation":592,"dataGaName":730},"Work","/small-business/","small business",{"text":732,"config":733},"Public Sector",{"icon":734,"href":735,"dataGaLocation":592,"dataGaName":736},"Organization","/solutions/public-sector/","public sector",{"text":738,"config":739},"Pricing",{"href":740,"dataGaName":741,"dataGaLocation":592,"dataNavLevelOne":741},"/pricing/","pricing",{"text":743,"config":744,"menu":746},"Resources",{"dataNavLevelOne":745},"resources",{"type":24,"link":747,"columns":751,"feature":845},{"text":748,"config":749},"View all resources",{"href":750,"dataGaName":745,"dataGaLocation":592},"/resources/",[752,785,812],{"title":753,"items":754},"Getting started",[755,760,765,770,775,780],{"text":756,"config":757},"Install",{"href":758,"dataGaName":759,"dataGaLocation":592},"/install/","install",{"text":761,"config":762},"Quick start guides",{"href":763,"dataGaName":764,"dataGaLocation":592},"/get-started/","quick setup checklists",{"text":766,"config":767},"Learn",{"href":768,"dataGaLocation":592,"dataGaName":769},"https://university.gitlab.com/","learn",{"text":771,"config":772},"Product documentation",{"href":773,"dataGaName":774,"dataGaLocation":592},"https://docs.gitlab.com/","product documentation",{"text":776,"config":777},"Best practice videos",{"href":778,"dataGaName":779,"dataGaLocation":592},"/getting-started-videos/","best practice videos",{"text":781,"config":782},"Integrations",{"href":783,"dataGaName":784,"dataGaLocation":592},"/integrations/","integrations",{"title":786,"items":787},"Discover",[788,793,798,803,807],{"text":789,"config":790},"Customer success stories",{"href":791,"dataGaName":792,"dataGaLocation":592},"/customers/","customer success stories",{"text":794,"config":795},"Blog",{"href":796,"dataGaName":797,"dataGaLocation":592},"/blog/","blog",{"text":799,"config":800},"Demo Hub",{"href":801,"dataGaName":802,"dataGaLocation":592},"/demo-hub/","demo hub",{"text":804,"config":805},"The Source",{"href":806,"dataGaName":797,"dataGaLocation":592},"/the-source/",{"text":808,"config":809},"Remote",{"href":810,"dataGaName":811,"dataGaLocation":592},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":813,"items":814},"Connect",[815,820,825,830,835,840],{"text":816,"config":817},"GitLab Services",{"href":818,"dataGaName":819,"dataGaLocation":592},"/services/","services",{"text":821,"config":822},"Contribute",{"href":823,"dataGaName":824,"dataGaLocation":592},"https://contributors.gitlab.com","contribute",{"text":826,"config":827},"Community",{"href":828,"dataGaName":829,"dataGaLocation":592},"/community/","community",{"text":831,"config":832},"Forum",{"href":833,"dataGaName":834,"dataGaLocation":592},"https://forum.gitlab.com/","forum",{"text":836,"config":837},"Events",{"href":838,"dataGaName":839,"dataGaLocation":592},"/events/","events",{"text":841,"config":842},"Partners",{"href":843,"dataGaName":844,"dataGaLocation":592},"/partners/","partners",{"config":846,"title":849,"text":850,"link":851},{"background":847,"textColor":848},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":852,"config":853},"Read the latest",{"href":854,"dataGaName":855,"dataGaLocation":592},"/whats-new/","whats new",{"text":857,"config":858,"menu":860},"Company",{"dataNavLevelOne":859},"company",{"type":24,"columns":861},[862],{"items":863},[864,869,875,877,882,887,892,897,902,907],{"text":865,"config":866},"About",{"href":867,"dataGaName":868,"dataGaLocation":592},"/company/","about",{"text":870,"config":871,"footerGa":874},"Jobs",{"href":872,"dataGaName":873,"dataGaLocation":592},"/jobs/","jobs",{"dataGaName":873},{"text":836,"config":876},{"href":838,"dataGaName":839,"dataGaLocation":592},{"text":878,"config":879},"Leadership",{"href":880,"dataGaName":881,"dataGaLocation":592},"/company/team/e-group/","leadership",{"text":883,"config":884},"Handbook",{"href":885,"dataGaName":886,"dataGaLocation":592},"https://handbook.gitlab.com/","handbook",{"text":888,"config":889},"Investor relations",{"href":890,"dataGaName":891,"dataGaLocation":592},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":893,"config":894},"Trust Center",{"href":895,"dataGaName":896,"dataGaLocation":592},"/security/","trust center",{"text":898,"config":899},"AI Transparency Center",{"href":900,"dataGaName":901,"dataGaLocation":592},"/ai-transparency-center/","ai transparency center",{"text":903,"config":904},"Newsletter",{"href":905,"dataGaName":906,"dataGaLocation":592},"/company/contact/#contact-forms","newsletter",{"text":908,"config":909},"Press",{"href":910,"dataGaName":911,"dataGaLocation":592},"/press/","press",{"text":913,"config":914,"menu":915},"Contact us",{"dataNavLevelOne":859},{"type":24,"columns":916},[917],{"items":918},[919,924,929],{"text":920,"config":921},"Talk to sales",{"href":922,"dataGaName":923,"dataGaLocation":592},"/sales/","talk to sales",{"text":925,"config":926},"Support portal",{"href":927,"dataGaName":928,"dataGaLocation":592},"https://support.gitlab.com/hc/en-us","support portal",{"text":930,"config":931},"Customer portal",{"href":932,"dataGaName":933,"dataGaLocation":592},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":935,"login":936,"suggestions":943},"Close",{"text":937,"link":938},"To search repositories and projects, login to",{"text":939,"config":940},"gitlab.com",{"href":606,"dataGaName":941,"dataGaLocation":942},"search login","search",{"text":944,"default":945},"Suggestions",[946,948,952,954,958,962],{"text":623,"config":947},{"href":628,"dataGaName":623,"dataGaLocation":942},{"text":949,"config":950},"Code Suggestions (AI)",{"href":951,"dataGaName":949,"dataGaLocation":942},"/solutions/code-suggestions/",{"text":658,"config":953},{"href":660,"dataGaName":658,"dataGaLocation":942},{"text":955,"config":956},"GitLab on AWS",{"href":957,"dataGaName":955,"dataGaLocation":942},"/partners/technology-partners/aws/",{"text":959,"config":960},"GitLab on Google Cloud",{"href":961,"dataGaName":959,"dataGaLocation":942},"/partners/technology-partners/google-cloud-platform/",{"text":963,"config":964},"Why GitLab?",{"href":636,"dataGaName":963,"dataGaLocation":942},{"freeTrial":966,"mobileIcon":971,"desktopIcon":976,"secondaryButton":979},{"text":967,"config":968},"Start free trial",{"href":969,"dataGaName":597,"dataGaLocation":970},"https://gitlab.com/-/trials/new/","nav",{"altText":972,"config":973},"Gitlab Icon",{"src":974,"dataGaName":975,"dataGaLocation":970},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":972,"config":977},{"src":978,"dataGaName":975,"dataGaLocation":970},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":980,"config":981},"Get Started",{"href":982,"dataGaName":983,"dataGaLocation":970},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":985,"mobileIcon":989,"desktopIcon":991},{"text":986,"config":987},"Learn more about GitLab Duo",{"href":628,"dataGaName":988,"dataGaLocation":970},"gitlab duo",{"altText":972,"config":990},{"src":974,"dataGaName":975,"dataGaLocation":970},{"altText":972,"config":992},{"src":978,"dataGaName":975,"dataGaLocation":970},{"button":994,"mobileIcon":999,"desktopIcon":1001},{"text":995,"config":996},"/switch",{"href":997,"dataGaName":998,"dataGaLocation":970},"#contact","switch",{"altText":972,"config":1000},{"src":974,"dataGaName":975,"dataGaLocation":970},{"altText":972,"config":1002},{"src":1003,"dataGaName":975,"dataGaLocation":970},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1005,"mobileIcon":1010,"desktopIcon":1012},{"text":1006,"config":1007},"Back to pricing",{"href":740,"dataGaName":1008,"dataGaLocation":970,"icon":1009},"back to pricing","GoBack",{"altText":972,"config":1011},{"src":974,"dataGaName":975,"dataGaLocation":970},{"altText":972,"config":1013},{"src":978,"dataGaName":975,"dataGaLocation":970},{"title":1015,"titleMobile":1016,"button":1017,"config":1022},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":634,"config":1018},{"href":1019,"dataGaName":1020,"dataGaLocation":1021},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1023,"disabled":571},"release",{"data":1025},{"text":1026,"source":1027,"edit":1033,"contribute":1038,"config":1043,"items":1048,"minimal":1257},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1028,"config":1029},"View page source",{"href":1030,"dataGaName":1031,"dataGaLocation":1032},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1034,"config":1035},"Edit this page",{"href":1036,"dataGaName":1037,"dataGaLocation":1032},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1039,"config":1040},"Please contribute",{"href":1041,"dataGaName":1042,"dataGaLocation":1032},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1044,"facebook":1045,"youtube":1046,"linkedin":1047},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1049,1096,1149,1193,1225],{"title":738,"links":1050,"subMenu":1065},[1051,1055,1060],{"text":1052,"config":1053},"View plans",{"href":740,"dataGaName":1054,"dataGaLocation":1032},"view plans",{"text":1056,"config":1057},"Why Premium?",{"href":1058,"dataGaName":1059,"dataGaLocation":1032},"/pricing/premium/","why premium",{"text":1061,"config":1062},"Why Ultimate?",{"href":1063,"dataGaName":1064,"dataGaLocation":1032},"/pricing/ultimate/","why ultimate",[1066],{"title":1067,"links":1068},"Contact Us",[1069,1072,1074,1076,1081,1086,1091],{"text":1070,"config":1071},"Contact sales",{"href":922,"dataGaName":602,"dataGaLocation":1032},{"text":925,"config":1073},{"href":927,"dataGaName":928,"dataGaLocation":1032},{"text":930,"config":1075},{"href":932,"dataGaName":933,"dataGaLocation":1032},{"text":1077,"config":1078},"Status",{"href":1079,"dataGaName":1080,"dataGaLocation":1032},"https://status.gitlab.com/","status",{"text":1082,"config":1083},"Terms of use",{"href":1084,"dataGaName":1085,"dataGaLocation":1032},"/terms/","terms of use",{"text":1087,"config":1088},"Privacy statement",{"href":1089,"dataGaName":1090,"dataGaLocation":1032},"/privacy/","privacy statement",{"text":1092,"config":1093},"Cookie preferences",{"dataGaName":1094,"dataGaLocation":1032,"id":1095,"isOneTrustButton":143},"cookie preferences","ot-sdk-btn",{"title":639,"links":1097,"subMenu":1106},[1098,1102],{"text":1099,"config":1100},"DevSecOps platform",{"href":621,"dataGaName":1101,"dataGaLocation":1032},"devsecops platform",{"text":1103,"config":1104},"AI-Assisted Development",{"href":628,"dataGaName":1105,"dataGaLocation":1032},"ai-assisted development",[1107],{"title":1108,"links":1109},"Topics",[1110,1115,1120,1124,1129,1134,1139,1144],{"text":1111,"config":1112},"CICD",{"href":1113,"dataGaName":1114,"dataGaLocation":1032},"/topics/ci-cd/","cicd",{"text":1116,"config":1117},"GitOps",{"href":1118,"dataGaName":1119,"dataGaLocation":1032},"/topics/gitops/","gitops",{"text":583,"config":1121},{"href":1122,"dataGaName":1123,"dataGaLocation":1032},"/topics/devops/","devops",{"text":1125,"config":1126},"Version Control",{"href":1127,"dataGaName":1128,"dataGaLocation":1032},"/topics/version-control/","version control",{"text":1130,"config":1131},"DevSecOps",{"href":1132,"dataGaName":1133,"dataGaLocation":1032},"/topics/devsecops/","devsecops",{"text":1135,"config":1136},"Cloud Native",{"href":1137,"dataGaName":1138,"dataGaLocation":1032},"/topics/cloud-native/","cloud native",{"text":1140,"config":1141},"AI for Coding",{"href":1142,"dataGaName":1143,"dataGaLocation":1032},"/topics/devops/ai-for-coding/","ai for coding",{"text":1145,"config":1146},"Agentic AI",{"href":1147,"dataGaName":1148,"dataGaLocation":1032},"/topics/agentic-ai/","agentic ai",{"title":1150,"links":1151},"Solutions",[1152,1154,1156,1161,1165,1168,1172,1175,1177,1180,1183,1188],{"text":682,"config":1153},{"href":677,"dataGaName":682,"dataGaLocation":1032},{"text":671,"config":1155},{"href":654,"dataGaName":655,"dataGaLocation":1032},{"text":1157,"config":1158},"Agile development",{"href":1159,"dataGaName":1160,"dataGaLocation":1032},"/solutions/agile-delivery/","agile delivery",{"text":1162,"config":1163},"SCM",{"href":667,"dataGaName":1164,"dataGaLocation":1032},"source code management",{"text":1111,"config":1166},{"href":660,"dataGaName":1167,"dataGaLocation":1032},"continuous integration & delivery",{"text":1169,"config":1170},"Value stream management",{"href":710,"dataGaName":1171,"dataGaLocation":1032},"value stream management",{"text":1116,"config":1173},{"href":1174,"dataGaName":1119,"dataGaLocation":1032},"/solutions/gitops/",{"text":720,"config":1176},{"href":723,"dataGaName":724,"dataGaLocation":1032},{"text":1178,"config":1179},"Small business",{"href":729,"dataGaName":730,"dataGaLocation":1032},{"text":1181,"config":1182},"Public sector",{"href":735,"dataGaName":736,"dataGaLocation":1032},{"text":1184,"config":1185},"Education",{"href":1186,"dataGaName":1187,"dataGaLocation":1032},"/solutions/education/","education",{"text":1189,"config":1190},"Financial services",{"href":1191,"dataGaName":1192,"dataGaLocation":1032},"/solutions/finance/","financial services",{"title":743,"links":1194},[1195,1197,1199,1201,1204,1206,1209,1211,1213,1215,1217,1219,1221,1223],{"text":756,"config":1196},{"href":758,"dataGaName":759,"dataGaLocation":1032},{"text":761,"config":1198},{"href":763,"dataGaName":764,"dataGaLocation":1032},{"text":766,"config":1200},{"href":768,"dataGaName":769,"dataGaLocation":1032},{"text":771,"config":1202},{"href":773,"dataGaName":1203,"dataGaLocation":1032},"docs",{"text":794,"config":1205},{"href":796,"dataGaName":797,"dataGaLocation":1032},{"text":1207,"config":1208},"What's new",{"href":854,"dataGaName":855,"dataGaLocation":1032},{"text":789,"config":1210},{"href":791,"dataGaName":792,"dataGaLocation":1032},{"text":808,"config":1212},{"href":810,"dataGaName":811,"dataGaLocation":1032},{"text":816,"config":1214},{"href":818,"dataGaName":819,"dataGaLocation":1032},{"text":821,"config":1216},{"href":823,"dataGaName":824,"dataGaLocation":1032},{"text":826,"config":1218},{"href":828,"dataGaName":829,"dataGaLocation":1032},{"text":831,"config":1220},{"href":833,"dataGaName":834,"dataGaLocation":1032},{"text":836,"config":1222},{"href":838,"dataGaName":839,"dataGaLocation":1032},{"text":841,"config":1224},{"href":843,"dataGaName":844,"dataGaLocation":1032},{"title":857,"links":1226},[1227,1229,1231,1233,1235,1237,1241,1246,1248,1250,1252],{"text":865,"config":1228},{"href":867,"dataGaName":859,"dataGaLocation":1032},{"text":870,"config":1230},{"href":872,"dataGaName":873,"dataGaLocation":1032},{"text":878,"config":1232},{"href":880,"dataGaName":881,"dataGaLocation":1032},{"text":883,"config":1234},{"href":885,"dataGaName":886,"dataGaLocation":1032},{"text":888,"config":1236},{"href":890,"dataGaName":891,"dataGaLocation":1032},{"text":1238,"config":1239},"Sustainability",{"href":1240,"dataGaName":1238,"dataGaLocation":1032},"/sustainability/",{"text":1242,"config":1243},"Diversity, inclusion and belonging (DIB)",{"href":1244,"dataGaName":1245,"dataGaLocation":1032},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":893,"config":1247},{"href":895,"dataGaName":896,"dataGaLocation":1032},{"text":903,"config":1249},{"href":905,"dataGaName":906,"dataGaLocation":1032},{"text":908,"config":1251},{"href":910,"dataGaName":911,"dataGaLocation":1032},{"text":1253,"config":1254},"Modern Slavery Transparency Statement",{"href":1255,"dataGaName":1256,"dataGaLocation":1032},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1258},[1259,1262,1265],{"text":1260,"config":1261},"Terms",{"href":1084,"dataGaName":1085,"dataGaLocation":1032},{"text":1263,"config":1264},"Cookies",{"dataGaName":1094,"dataGaLocation":1032,"id":1095,"isOneTrustButton":143},{"text":1266,"config":1267},"Privacy",{"href":1089,"dataGaName":1090,"dataGaLocation":1032},[1269],{"id":1270,"title":1271,"body":570,"config":1272,"content":1274,"description":570,"extension":1278,"meta":1279,"navigation":143,"path":1280,"seo":1281,"stem":1282,"__hash__":1283},"blogAuthors/en-us/blog/authors/pj-metz.yml","Pj Metz",{"template":1273},"BlogAuthor",{"name":7,"config":1275},{"headshot":1276,"ctfId":1277},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","PjMetz","yml",{},"/en-us/blog/authors/pj-metz",{},"en-us/blog/authors/pj-metz","SgW84Gu-lPq0zFzhy1aT23bZjx9kWViDG_WXzCPn04E",[1285,1294,1302],{"title":1286,"description":1287,"heroImage":1288,"category":566,"date":1289,"authors":1290,"slug":1293,"externalUrl":570},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[1291,1292],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1295,"description":1296,"heroImage":1297,"category":566,"date":1298,"authors":1299,"slug":1301,"externalUrl":570},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[1300],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1303,"description":1304,"heroImage":1305,"category":566,"date":1306,"authors":1307,"slug":1309,"externalUrl":570},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[1308],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1311},[1312,1326,1338,1350],{"id":1313,"categories":1314,"header":1316,"text":1317,"button":1318,"image":1323},"ai-modernization",[1315],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1319,"config":1320},"Get your AI maturity score",{"href":1321,"dataGaName":1322,"dataGaLocation":797},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1324},{"src":1325},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1327,"categories":1328,"header":1330,"text":1317,"button":1331,"image":1335},"devops-modernization",[1329,1133],"product","Are you just managing tools or shipping innovation?",{"text":1332,"config":1333},"Get your DevOps maturity score",{"href":1334,"dataGaName":1322,"dataGaLocation":797},"/assessments/devops-modernization-assessment/",{"config":1336},{"src":1337},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1339,"categories":1340,"header":1342,"text":1317,"button":1343,"image":1347},"security-modernization",[1341],"security","Are you trading speed for security?",{"text":1344,"config":1345},"Get your security maturity score",{"href":1346,"dataGaName":1322,"dataGaLocation":797},"/assessments/security-modernization-assessment/",{"config":1348},{"src":1349},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1351,"paths":1352,"header":1355,"text":1356,"button":1357,"image":1362},"github-azure-migration",[1353,1354],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1358,"config":1359},"See how GitLab compares to GitHub",{"href":1360,"dataGaName":1361,"dataGaLocation":797},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1363},{"src":1337},{"header":1365,"blurb":1366,"button":1367,"secondaryButton":1372},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1368,"config":1369},"Get your free trial",{"href":1370,"dataGaName":597,"dataGaLocation":1371},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1070,"config":1373},{"href":922,"dataGaName":602,"dataGaLocation":1371},1786803771114]